Load in libraries
library(tidyverse)
library(here)
library(janitor)
library(tsibble)
library(lubridate)
library(sf)
Load in data sets
waiting_times_raw <- read_csv(here("raw_data/non_covid/monthly_ae_waitingtimes_202206.csv")) %>%
clean_names()
hb <- read_csv(here("clean_data/hb_list_simple.csv"))
hospitals <- read_csv(here("raw_data/general/current-hospital_flagged20211216.csv")) %>%
clean_names() %>%
select(location, location_name)
clean dataset
The following cleaning does the following to the waiting times data
set: - converts month column to year_month dates and extracts years and
months
- joins health board and hospital names to data set
- renames columns to more easily understandable names
- removes columns relating to “episodes”, “qualifier codes” and
“discharges” - adds new value of wait greater than 4 hours to the
data
- replaces all NA values with 0 (this step may be optional)
Please note that 4 hours wait time is the “Target” wait time for the
NHS and is represented by the “wait_lt_4hrs” column values.
# cleaning script
waiting_times <- waiting_times_raw %>%
mutate(date_ym = ym(month), .before = month,
month = month(date_ym, label = TRUE, abbr = FALSE),
year = year(date_ym)) %>%
left_join(hb, c("hbt" = "hb")) %>%
left_join(hospitals, c("treatment_location" = "location")) %>%
rename(total_attendance = number_of_attendances_aggregate,
wait_lt_4hrs = number_meeting_target_aggregate,
wait_gt_8hrs = attendance_greater8hrs,
wait_gt_12hrs = attendance_greater12hrs,
hospital_id = treatment_location,
hospital_name = location_name) %>%
select(date_ym, year, month, hb_name, hospital_id, hospital_name, department_type,
total_attendance, wait_lt_4hrs, wait_gt_8hrs, wait_gt_12hrs) %>%
mutate(wait_gt_4hrs = total_attendance - wait_lt_4hrs, .after = wait_lt_4hrs) %>%
mutate(across(total_attendance:wait_gt_12hrs, .fns = ~coalesce(., 0)))
waiting_times <- read_csv(here("clean_data/wait_times.csv")) %>%
mutate(month = month(date_ym, label = TRUE, abbr = FALSE))
# create table with proportions of wait times used for the analysis
waiting_times_prop <- waiting_times %>%
pivot_longer(contains("wait"), names_to = "wait_category", values_to = "number_of_attendances") %>%
mutate(wait_prop = number_of_attendances / total_attendance,
wait_category = str_replace(wait_category, "wait", "prop")) %>%
select(-number_of_attendances) %>%
pivot_wider(names_from = wait_category, values_from = wait_prop)
waiting_times_prop
Analysis
How does hospital attendances change with time?
# plot all data - attendances per year
waiting_times %>%
group_by(year) %>%
summarise(total_attendance = sum(total_attendance)) %>%
ggplot(aes(x = year, y = total_attendance)) +
geom_line()
# attendances - all data covid seasonal analysis
waiting_times %>%
group_by(year, month) %>%
summarise(total_attendance = sum(total_attendance)) %>%
ggplot(aes(x = month, y = total_attendance, group = year, col = factor(year))) +
geom_line()
# attendances per month - pre-covid seasonal analysis
waiting_times %>%
filter(year < 2020) %>%
group_by(year, month) %>%
summarise(total_attendance = sum(total_attendance)) %>%
ggplot(aes(x = month, y = total_attendance, group = year, col = factor(year))) +
geom_line()
# attendances per month - covid seasonal analysis
waiting_times %>%
filter(year >= 2020) %>%
group_by(year, month) %>%
summarise(total_attendance = sum(total_attendance)) %>%
ggplot(aes(x = month, y = total_attendance, group = year, col = factor(year))) +
geom_line()
health_board_input <- c("Borders", "Lothian", "Ayrshire and Arran", "Dumfries and Galloway")
# health_board_input <- hb$hb_name
paste("Multiple HB:\n", paste(sort(health_board_input), collapse = ", "), sep = "\n")
str_c("Multiple HBs:\n", str_c("Borders", "Lothian", "Dumfries", sep = ",\n"))
# plot all data - attendances per year
if(length(health_board_input) <= 3) {
#first two rows will be from reactive function
p <- waiting_times %>%
filter(hb_name %in% health_board_input) %>%
group_by(date_ym, hb_name) %>%
summarise(total_attendance = sum(total_attendance)) %>%
ggplot(aes(x = date_ym, y = total_attendance, col = hb_name)) +
geom_line()
} else {
if(length(health_board_input) == 14) {
hb_label <- "All Health Boards"
} else {
hb_label <- str_c("Total of Multiple HBs:\n",
str_c(health_board_input, collapse = ",\n"))
}
p <- waiting_times %>%
filter(hb_name %in% health_board_input) %>%
mutate(hb_label = hb_label) %>%
group_by(date_ym) %>%
summarise(total_attendance = sum(total_attendance)) %>%
ggplot(aes(x = date_ym, y = total_attendance, colour = hb_label)) +
geom_line()
}
p +
theme_classic() +
scale_y_continuous(labels = comma,
expand = c(0, 0),
limits = c(0, NA)) +
scale_x_date(date_labels = "%Y",
date_breaks = "1 year") +
labs(title = "Total hospital attendances",
subtitle = "July 2007 to June 2022",
col = "Health Board",
y = "Total attendances") +
theme(axis.title.x = element_blank(),
axis.text.x = element_text(angle = 45, hjust = 1),
legend.text.align = 0)
How do wait times change per year? (in terms of numbers)
# wait times less than 4 hours
waiting_times %>%
group_by(year) %>%
summarise(wait_lt_4hrs = sum(wait_lt_4hrs)) %>%
ggplot(aes(x = year, y = wait_lt_4hrs)) +
geom_col()
# wait times more than 4 hours
waiting_times %>%
group_by(year) %>%
summarise(wait_gt_4hrs = sum(wait_gt_4hrs)) %>%
ggplot(aes(x = year, y = wait_gt_4hrs)) +
geom_col()
# wait times more than 8 hours
waiting_times %>%
group_by(year) %>%
summarise(wait_gt_8hrs = sum(wait_gt_8hrs)) %>%
ggplot(aes(x = year, y = wait_gt_8hrs)) +
geom_col()
# wait times more than 12 hours
waiting_times %>%
group_by(year) %>%
summarise(wait_gt_12hrs = sum(wait_gt_12hrs)) %>%
ggplot(aes(x = year, y = wait_gt_12hrs)) +
geom_col()
How do wait times change per year? (in terms of proportion)
# wait times less than 4 hours
waiting_times %>%
group_by(year) %>%
summarise(total_attendance = sum(total_attendance),
wait_lt_4hrs = sum(wait_lt_4hrs),
prop_lt_4hrs = wait_lt_4hrs / total_attendance) %>%
ggplot(aes(x = year, y = prop_lt_4hrs)) +
geom_col()
# wait times more than 4 hours
waiting_times %>%
group_by(year) %>%
summarise(total_attendance = sum(total_attendance),
wait_gt_4hrs = sum(wait_gt_4hrs),
prop_gt_4hrs = wait_gt_4hrs / total_attendance) %>%
ggplot(aes(x = year, y = prop_gt_4hrs)) +
geom_col()
# wait times more than 8 hours
waiting_times %>%
group_by(year) %>%
summarise(total_attendance = sum(total_attendance),
wait_gt_8hrs = sum(wait_gt_8hrs),
prop_gt_8hrs = wait_gt_8hrs / total_attendance) %>%
ggplot(aes(x = year, y = prop_gt_8hrs)) +
geom_col()
# wait times more than 12 hours
waiting_times %>%
group_by(year) %>%
summarise(total_attendance = sum(total_attendance),
wait_gt_12hrs = sum(wait_gt_12hrs),
prop_gt_12hrs = wait_gt_12hrs / total_attendance) %>%
ggplot(aes(x = year, y = prop_gt_12hrs)) +
geom_col() +
scale_y_continuous(expand = c(0,0),
labels = scales::percent) +
theme_classic() +
theme(axis.title.x = element_blank()) +
labs(y = "Percentage of attendances greater than 12 hours",
title = "Wait times of >12hours each year")
How do wait times differ between departments? (in terms of
proportions)
# wait times less than 4 hours
waiting_times %>%
group_by(year, department_type) %>%
summarise(total_attendance = sum(total_attendance),
wait_lt_4hrs = sum(wait_lt_4hrs),
prop_lt_4hrs = wait_lt_4hrs / total_attendance) %>%
ggplot(aes(x = year, y = prop_lt_4hrs, fill = department_type)) +
geom_col(position = "dodge")
# wait times more than 4 hours
waiting_times %>%
group_by(year, department_type) %>%
summarise(total_attendance = sum(total_attendance),
wait_gt_4hrs = sum(wait_gt_4hrs),
prop_gt_4hrs = wait_gt_4hrs / total_attendance) %>%
ggplot(aes(x = year, y = prop_gt_4hrs, fill = department_type)) +
geom_col(position = "dodge")
# wait times more than 8 hours
waiting_times %>%
group_by(year, department_type) %>%
summarise(total_attendance = sum(total_attendance),
wait_gt_8hrs = sum(wait_gt_8hrs),
prop_gt_8hrs = wait_gt_8hrs / total_attendance) %>%
ggplot(aes(x = year, y = prop_gt_8hrs, fill = department_type)) +
geom_col(position = "dodge")
# wait times more than 12 hours
waiting_times %>%
group_by(year, department_type) %>%
summarise(total_attendance = sum(total_attendance),
wait_gt_12hrs = sum(wait_gt_12hrs),
prop_gt_12hrs = wait_gt_12hrs / total_attendance) %>%
ggplot(aes(x = year, y = prop_gt_12hrs, fill = department_type)) +
geom_col(position = "dodge")
How do wait times change per year & month? (in terms of
numbers)
# wait times less than 4 hours
waiting_times %>%
group_by(year, month) %>%
summarise(wait_lt_4hrs = sum(wait_lt_4hrs)) %>%
ggplot(aes(x = month, y = wait_lt_4hrs, group = year, col = factor(year))) +
geom_line()
# wait times more than 4 hours
waiting_times %>%
group_by(year, month) %>%
summarise(wait_gt_4hrs = sum(wait_gt_4hrs)) %>%
ggplot(aes(x = month, y = wait_gt_4hrs, group = year, col = factor(year))) +
geom_line()
# wait times more than 8 hours
waiting_times %>%
group_by(year, month) %>%
summarise(wait_gt_8hrs = sum(wait_gt_8hrs)) %>%
ggplot(aes(x = month, y = wait_gt_8hrs, group = year, col = factor(year))) +
geom_line()
# wait times more than 12 hours
waiting_times %>%
group_by(year, month) %>%
summarise(wait_gt_12hrs = sum(wait_gt_12hrs)) %>%
ggplot(aes(x = month, y = wait_gt_12hrs, group = year, col = factor(year))) +
geom_line()
How do wait times vary across health boards?
# in terms of numbers
waiting_times %>%
group_by(date_ym, health_board) %>%
summarise(wait_gt_8hrs = sum(wait_gt_8hrs)) %>%
ggplot(aes(x = date_ym, y = wait_gt_8hrs, col = health_board)) +
geom_line() +
labs(title = "Number of waits > 8 hours for each healthboard")
# in terms of proportion
waiting_times_prop %>%
group_by(date_ym, health_board) %>%
summarise(prop_gt_8hrs = sum(total_attendance * prop_gt_8hrs)/
sum(total_attendance)) %>%
ggplot(aes(x = date_ym, y = prop_gt_8hrs, col = health_board)) +
geom_line() +
labs(title = "Proportion of waits > 8 hours for each healthboard")
# find top 5 healthboards (in terms of attendances)
top_5_attendances_by_hb <- waiting_times_prop %>%
group_by(health_board) %>%
summarise(total_att = sum(total_attendance)) %>%
slice_max(total_att, n = 5)
# find bottom 5 healthboards (in terms of attendances)
bottom_5_attendances_by_hb <- waiting_times_prop %>%
group_by(health_board) %>%
summarise(total_att = sum(total_attendance)) %>%
slice_min(total_att, n = 5)
# wait times across the top 5 healthboards > 8 hours
waiting_times_prop %>%
filter(health_board %in% top_5_attendances_by_hb$health_board) %>%
group_by(date_ym, health_board) %>%
summarise(prop_gt_8hrs = sum(total_attendance * prop_gt_8hrs)/
sum(total_attendance)) %>%
ggplot(aes(x = date_ym, y = prop_gt_8hrs, col = health_board)) +
geom_line() +
labs(title = "Proportion of waits > 8 hours for the top 5 most attended healthboards")
# wait times across the bottom 5 healthboards > 8 hours
waiting_times_prop %>%
filter(health_board %in% bottom_5_attendances_by_hb$health_board) %>%
group_by(date_ym, health_board) %>%
summarise(prop_gt_8hrs = sum(total_attendance * prop_gt_8hrs)/
sum(total_attendance)) %>%
ggplot(aes(x = date_ym, y = prop_gt_8hrs, col = health_board)) +
geom_line() +
labs(title = "Proportion of waits > 8 hours for the bottom 5 most attended healthboards")
# wait times across the top 5 healthboards > 12 hours
waiting_times_prop %>%
filter(health_board %in% top_5_attendances_by_hb$health_board) %>%
group_by(date_ym, health_board) %>%
summarise(prop_gt_12hrs = sum(total_attendance * prop_gt_12hrs)/
sum(total_attendance)) %>%
ggplot(aes(x = date_ym, y = prop_gt_12hrs, col = health_board)) +
geom_line() +
labs(title = "Proportion of waits > 12 hours for the bottom 5 most attended healthboards")
# wait times across the bottom 5 healthboards > 12 hours
waiting_times_prop %>%
filter(health_board %in% bottom_5_attendances_by_hb$health_board) %>%
group_by(date_ym, health_board) %>%
summarise(prop_gt_12hrs = sum(total_attendance * prop_gt_12hrs)/
sum(total_attendance)) %>%
ggplot(aes(x = date_ym, y = prop_gt_12hrs, col = health_board)) +
geom_line() +
labs(title = "Proportion of waits > 12 hours for the bottom 5 most attended healthboards")
# wait times across each hospital in the Borders healthboard
waiting_times_prop %>%
# filter(health_board == "NHS Borders") %>%
group_by(date_ym, hospital_name) %>%
summarise(prop_gt_8hrs = sum(total_attendance * prop_gt_8hrs)/
sum(total_attendance)) %>%
ggplot(aes(x = date_ym, y = prop_gt_8hrs, col = hospital_name)) +
geom_line() +
labs(title = "Proportion of waits > 8 hours for the bottom 5 most attended healthboards") +
theme(legend.position = "none")
most affected healthboards
# in terms of proportion
top_5_hospital_props <- waiting_times_prop %>%
group_by(hospital_name) %>%
summarise(max_prop = max(prop_gt_12hrs)) %>%
arrange(desc(max_prop)) %>%
slice_max(max_prop, n = 5)
# in terms of numbers
waiting_times %>%
group_by(hospital_name) %>%
summarise(max_prop = max(wait_gt_12hrs)) %>%
arrange(desc(max_prop))
# wait times across each hospital in the Borders healthboard
waiting_times_prop %>%
filter(hospital_name %in% top_5_hospital_props$hospital_name) %>%
group_by(date_ym, hospital_name) %>%
summarise(prop_gt_12hrs = sum(total_attendance * prop_gt_12hrs)/
sum(total_attendance)) %>%
ggplot(aes(x = date_ym, y = prop_gt_12hrs, col = hospital_name)) +
geom_line() +
labs(title = "Proportion of waits > 8 hours for the bottom 5 most attended healthboards")
For the years 2007 to 2019, provide a summary of the effects of wait
times at different times of the year.
waiting_times_summary <- waiting_times_prop %>%
filter(year <= 2019) %>%
mutate(month = factor(month, levels = c("July", "August", "September", "October", "November", "December", "January", "February", "March", "April", "May", "June"))) %>%
group_by(month) %>%
summarise(total_attends = mean(total_attendance),
prop_lt_4hrs = sum(total_attendance * prop_lt_4hrs)/ sum(total_attendance),
prop_gt_4hrs = sum(total_attendance * prop_gt_4hrs)/ sum(total_attendance),
prop_gt_8hrs = sum(total_attendance * prop_gt_8hrs)/ sum(total_attendance),
prop_gt_12hrs = sum(total_attendance * prop_gt_12hrs)/ sum(total_attendance))
waiting_times_summary %>%
ggplot(aes(x = month, y = total_attends)) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
axis.title.x = element_blank()) +
labs(y = "Average monthly attendances",
title = "Average A&E attendances",
subtitle = "From July 2007 to December 2019 ") +
geom_smooth()
waiting_times_summary %>%
ggplot(aes(x = month, y = prop_lt_4hrs, group = 1)) +
geom_point() +
labs(title = "Seasonality of proportion of visits with a wait time < 4 hours",
subtitle = "2007 to 2019") +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
geom_smooth()
waiting_times_summary %>%
ggplot(aes(x = month, y = prop_gt_4hrs, group = 1)) +
geom_point() +
labs(title = "Seasonality of proportion of visits with a wait time > 4 hours",
subtitle = "2007 to 2019") +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
geom_smooth()
waiting_times_summary %>%
ggplot(aes(x = month, y = prop_gt_8hrs, group = 1)) +
geom_point() +
labs(title = "Seasonality of proportion of visits with a wait time > 8 hours",
subtitle = "2007 to 2019") +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
geom_smooth()
waiting_times_summary %>%
ggplot(aes(x = month, y = prop_gt_12hrs, group = 1)) +
geom_point() +
scale_y_continuous(labels = scales::percent) +
labs(title = "Seasonality of proportion of visits with a wait time > 12 hours",
subtitle = "Pre-covid: 2007 to 2019",
y = "Percentage of attendances > 12 hours") +
theme_classic() +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
axis.title.x = element_blank()) +
geom_smooth(se = FALSE)
The number of A&E attendances decrease during the winter months
however the proportion of wait times greater than 4hours increases
significantly between November and February highlighting that the
complexity of cases in the winter mean that it takes hospitals longer to
discharge patients. Perhaps combining this output with the bed
occupation rates during the winter months could further supplement this
relationship.
waiting_times_prop %>%
# filter(year <= 2019) %>%
mutate(month = factor(month, levels = c("July", "August", "September", "October", "November", "December", "January", "February", "March", "April", "May", "June"))) %>%
group_by(month, health_board) %>%
summarise(total_attends = mean(total_attendance),
prop_lt_4hrs = sum(total_attendance * prop_lt_4hrs)/ sum(total_attendance),
prop_gt_4hrs = sum(total_attendance * prop_gt_4hrs)/ sum(total_attendance),
prop_gt_8hrs = sum(total_attendance * prop_gt_8hrs)/ sum(total_attendance),
prop_gt_12hrs = sum(total_attendance * prop_gt_12hrs)/ sum(total_attendance)) %>%
ggplot(aes(x = month, y = prop_gt_12hrs, group = health_board, colour = health_board)) +
geom_line() +
labs(title = "Seasonality of proportion of visits with a wait time > 12 hours") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
How do attendances to different specialties change over time?
specialties_raw <- read_csv(here("raw_data/non_covid/inpatient_and_daycase_by_nhs_board_of_treatment_and_specialty.csv")) %>%
clean_names()
specialties_raw
specialties <- specialties_raw %>%
inner_join(hb, "hb") %>%
inner_join(hospitals, "location") %>%
select(-ends_with("qf"), -hb, - specialty) %>%
select(quarter, hb_name, location, location_name, everything()) %>%
mutate(year = as.numeric(str_sub(quarter,1, 4)), .before = quarter) %>%
mutate(is_covid_year = case_when(
year >= 2020 ~ TRUE,
year < 2020 ~ FALSE
))
# mutate(quarter = str_sub(quarter, -2, -1))
specialties
all episodes vs time
specialties %>%
distinct(admission_type)
specialties %>%
group_by(quarter) %>%
filter(admission_type == "All Inpatients and Day cases") %>%
summarise(total_episodes = sum(episodes)) %>%
ggplot(aes(x = quarter, y = total_episodes, group = 1)) +
geom_line() +
geom_point() +
theme_classic() +
scale_y_continuous(labels = scales::comma, expand = c(0,0), limits = c(0,NA)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(title = "Total admissions for All Inpatients and Day Cases",
x = "Quarter",
y = "Total Episodes")
All Day Cases
specialties %>%
distinct(admission_type)
specialties %>%
group_by(quarter, admission_type) %>%
filter(admission_type %in% c("All Day cases", "All Inpatients")) %>%
summarise(total_episodes = sum(episodes)) %>%
ggplot(aes(x = quarter, y = total_episodes, colour = admission_type)) +
geom_line(aes(group = admission_type)) +
geom_point() +
theme_classic() +
scale_y_continuous(labels = scales::comma, expand = c(0,0), limits = c(0,NA)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(title = "Total admissions for All Day Cases and All Inpatients",
x = "Quarter",
y = "Total Episodes",
col = "Admission Type")
all_inpatient_cats <- c("Elective Inpatients",
"Emergency Inpatients",
"Transfers")
specialties %>%
group_by(quarter, admission_type) %>%
filter(admission_type %in% all_inpatient_cats) %>%
summarise(total_episodes = sum(episodes)) %>%
ggplot(aes(x = quarter, y = total_episodes, colour = admission_type)) +
geom_line(aes(group = admission_type)) +
geom_point() +
theme_classic() +
scale_y_continuous(labels = scales::comma, expand = c(0,0), limits = c(0,NA)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(title = "Total admissions for Inpatients",
x = "Quarter",
y = "Total Episodes",
col = "Admission Type")
specialties %>%
distinct(admission_type, specialty_name)
specialties %>%
group_by(quarter, admission_type, specialty_name) %>%
filter(admission_type == "Emergency Inpatients") %>%
summarise(total_episodes = sum(episodes)) %>%
ggplot(aes(x = quarter, y = total_episodes, colour = specialty_name)) +
geom_line(aes(group = specialty_name)) +
geom_point() +
theme_classic() +
scale_y_continuous(labels = scales::comma, expand = c(0,0), limits = c(0,10000)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(title = "Total admissions for Emergency Inpatients",
subtitle = "Split by specialty",
x = "Quarter",
y = "Total Episodes",
col = "Admission Type")
Which departments changed the most between Covid and pre-covid
total_admissions <- specialties %>%
group_by(is_covid_year) %>%
filter(admission_type == "All Inpatients and Day cases") %>%
summarise(total_admissions = sum(episodes)) %>%
pull(total_admissions)
change_in_at_specialties <- specialties %>%
filter(admission_type %in% c(all_inpatient_cats, "All Day cases")) %>%
group_by(admission_type, specialty_name, is_covid_year) %>%
summarise(total_episodes = sum(episodes)) %>%
pivot_wider(names_from = is_covid_year, values_from = total_episodes) %>%
rename("covid_year" = "TRUE", "pre_covid_year" = "FALSE") %>%
mutate(pre_covid_year_prop = pre_covid_year / total_admissions[1],
covid_year_prop = covid_year / total_admissions[2],
percentage_change = ((covid_year_prop / pre_covid_year_prop) - 1) * 100) %>%
ungroup()
specialties %>%
filter(admission_type == "All Day cases" & specialty_name == "Cardiothoracic Surgery") %>%
group_by(is_covid_year) %>%
summarise(count = sum(episodes))
# top 5 changes in specialty proportion
change_in_at_specialties %>%
slice_max(percentage_change, n = 5)
# sort by largest proportion, top 5
change_in_at_specialties %>%
slice_max(percentage_change, n = 5) %>%
arrange(desc(covid_year_prop))
change_in_at_specialties %>%
filter(covid_year > 1000) %>%
slice_max(percentage_change, n = 5) %>%
mutate(label = str_c(specialty_name, "\n(", admission_type, ")")) %>%
ggplot(aes(x = reorder(label, sort(percentage_change)),
y = percentage_change)) +
geom_col() +
theme_classic() +
scale_y_continuous(expand = c(0,0)) +
theme(axis.title.x = element_blank(),
axis.text.x = element_text(size = 8)) +
labs(y = "Percentage Increase (%)",
title = "Top 5 increases in hospital admissions (by specialty and admission type)",
subtitle = "More than 1,000 admissions")
change_in_specialties <- specialties %>%
group_by(specialty_name, is_covid_year) %>%
summarise(total_episodes = sum(episodes)) %>%
pivot_wider(names_from = is_covid_year, values_from = total_episodes) %>%
rename("covid_year" = "TRUE", "pre_covid_year" = "FALSE") %>%
mutate(pre_covid_year_prop = pre_covid_year / total_admissions[1],
covid_year_prop = covid_year / total_admissions[2],
percentage_change = ((covid_year_prop / pre_covid_year_prop) - 1) * 100) %>%
ungroup()
change_in_specialties %>%
slice_max(percentage_change, n = 5) %>%
filter(percentage_change > 0) %>%
arrange(desc(percentage_change)) %>%
ggplot(aes(x = reorder(specialty_name, percentage_change, decreasing = TRUE),
y = percentage_change)) +
geom_col() +
theme_classic() +
scale_y_continuous(expand = c(0,0)) +
theme(axis.title.x = element_blank(),
axis.text.x = element_text(size = 8)) +
labs(y = "Percentage Increase (%)",
title = "Top 5 changes in hospital admissions (by specialty) - pre-Covid vs Covid",
subtitle = "More than 1,000 admissions")
wt_with_discharges <- waiting_times_raw %>%
mutate(date_ym = ym(month), .before = month,
month = month(date_ym, label = TRUE, abbr = FALSE),
year = year(date_ym)) %>%
left_join(hb, c("hbt" = "hb")) %>%
left_join(hospitals, c("treatment_location" = "location")) %>%
rename(total_attendance = number_of_attendances_aggregate,
wait_lt_4hrs = number_meeting_target_aggregate,
wait_gt_8hrs = attendance_greater8hrs,
wait_gt_12hrs = attendance_greater12hrs,
health_board = hb_name,
hospital_id = treatment_location,
hospital_name = location_name) %>%
select(-ends_with("qf")) %>%
select(date_ym, year, month, health_board, hospital_id, hospital_name,
everything(), -country, - hbt)
# check if there is a trend across all years
wt_with_discharges %>%
group_by(date_ym, hospital_name) %>%
summarise(transfers = sum(discharge_destination_transfer, na.rm = TRUE)) %>%
ggplot(aes(x = date_ym, y = transfers, col = hospital_name)) +
geom_line() +
theme(legend.position = "none")
# check if there is a seasonal trend
wt_with_discharges %>%
mutate(month = factor(month, levels = c("July", "August", "September", "October", "November", "December", "January", "February", "March", "April", "May", "June"))) %>%
group_by(month, health_board) %>%
summarise(transfers = sum(discharge_destination_other_specialty, na.rm = TRUE)) %>%
ggplot(aes(x = month, y = transfers, group = health_board, col = health_board)) +
geom_line() +
theme(legend.position = "none") +
facet_wrap(~ health_board, scales = "free_y") +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
Bed occupancy data
beds_raw <- read_csv(here("raw_data/non_covid/beds_by_nhs_board_of_treatment_and_specialty.csv")) %>%
clean_names() %>%
select(-ends_with("qf"))
# all specialty names
beds_raw %>%
group_by(specialty_name) %>%
summarise(sum(all_staffed_beddays))
beds_raw %>%
filter(specialty_name != "All Acute" & specialty_name != "All Specialties") %>%
# group_by(specialty_name) %>%
summarise(sum(all_staffed_beddays))
# 209139660
beds <- beds_raw %>%
left_join(hb, "hb") %>%
left_join(hospitals, "location") %>%
select(quarter, hb, hb_name, location, location_name, specialty_name:percentage_occupancy) %>%
mutate()
beds %>%
group_by(quarter) %>%
summarise(staffed_beds = sum(all_staffed_beddays),
occupied_beds = sum(total_occupied_beddays),
occupation_percentage = occupied_beds / staffed_beds * 100) %>%
ggplot(aes(x = quarter, y = occupation_percentage, group = 1)) +
geom_line()
Wait times - baseline (pre-covid vs covid)
Percentage of wait times within target (<4hrs)
# pre-covid <= 2019, covid => 2020
avg_wt_target_pre_covid <- waiting_times %>%
filter(year <= 2019) %>%
group_by(month) %>%
summarise(total_attendance = sum(total_attendance),
total_wait_lt_4hrs = sum(wait_lt_4hrs),
target_wait_prop = total_wait_lt_4hrs / total_attendance)
avg_wt_target_pre_covid %>%
ggplot(aes(x = month, y = target_wait_prop, group = 1)) +
geom_line() +
geom_smooth(se = 0)
waiting_times %>%
filter(year >= 2020) %>%
group_by(year, month) %>%
summarise(total_attendance = sum(total_attendance),
total_wait_lt_4hrs = sum(wait_lt_4hrs),
target_wait_prop = total_wait_lt_4hrs / total_attendance) %>%
ggplot(aes(x = month, y = target_wait_prop,
group = factor(year), col = factor(year))) +
geom_line() +
geom_point() +
geom_line(data = avg_wt_target_pre_covid, aes(x = month, y = target_wait_prop,
group = 1, colour = "Baseline"),
size = 1) +
geom_point(data = avg_wt_target_pre_covid, aes(x = month, y = target_wait_prop,
group = 1, colour = "Baseline")) +
theme_classic() +
scale_color_manual(name = "Year", values = c("Baseline" = "darkblue",
"2020" = "red",
"2021" = "green",
"2022" = "orange")) +
scale_y_continuous(labels = scales::percent) +
labs(y = "Percentage of admissions (%)",
title = "Proportion of waiting times greater than 12 hours",
subtitle = "Pre-covid (2007-2019) vs covid (2020+)",
col = "Year") +
theme(axis.title.x = element_blank(),
axis.text.x = element_text(angle = 45, hjust = 1))
Percentage of wait times >8hrs
avg_wt_gt_8hrs_pre_covid <- waiting_times %>%
filter(year <= 2019) %>%
group_by(month) %>%
summarise(total_attendance = sum(total_attendance),
total_wait_gt_8hrs = sum(wait_gt_8hrs),
target_wait_prop = total_wait_gt_8hrs / total_attendance)
avg_wt_gt_8hrs_pre_covid %>%
ggplot(aes(x = month, y = target_wait_prop, group = 1)) +
geom_line() +
geom_smooth(se = 0)
waiting_times %>%
filter(year >= 2020) %>%
group_by(year, month) %>%
summarise(total_attendance = sum(total_attendance),
total_wait_gt_8hrs = sum(wait_gt_8hrs),
target_wait_prop = total_wait_gt_8hrs / total_attendance) %>%
ggplot(aes(x = month, y = target_wait_prop,
group = factor(year), col = factor(year))) +
geom_line() +
geom_point() +
geom_line(data = avg_wt_gt_8hrs_pre_covid, aes(x = month, y = target_wait_prop,
group = 1, colour = "Baseline"),
size = 1) +
geom_point(data = avg_wt_gt_8hrs_pre_covid, aes(x = month, y = target_wait_prop,
group = 1, colour = "Baseline")) +
theme_classic() +
scale_color_manual(name = "Year", values = c("Baseline" = "darkblue", "2020" = "red", "2021" = "green", "2022" = "orange")) +
scale_y_continuous(labels = scales::percent) +
labs(y = "Percentage of admissions (%)",
title = "Proportion of waiting times greater than 8 hours",
subtitle = "Pre-covid (2007-2019) vs covid (2020+)",
col = "Year") +
theme(axis.title.x = element_blank(),
axis.text.x = element_text(angle = 45, hjust = 1))
Percentage of wait times >12hrs
avg_wt_gt_12hrs_pre_covid <- waiting_times %>%
filter(year <= 2019) %>%
group_by(month) %>%
summarise(total_attendance = sum(total_attendance),
total_wait_gt_12hrs = sum(wait_gt_12hrs),
target_wait_prop = total_wait_gt_12hrs / total_attendance)
avg_wt_gt_12hrs_pre_covid %>%
ggplot(aes(x = month, y = target_wait_prop, group = 1)) +
geom_line() +
geom_smooth(se = 0)
waiting_times %>%
filter(year >= 2020) %>%
group_by(year, month) %>%
summarise(total_attendance = sum(total_attendance),
total_wait_gt_12hrs = sum(wait_gt_12hrs),
target_wait_prop = total_wait_gt_12hrs / total_attendance) %>%
ggplot(aes(x = month, y = target_wait_prop,
group = factor(year), col = factor(year))) +
geom_line() +
geom_point() +
geom_line(data = avg_wt_gt_12hrs_pre_covid, aes(x = month, y = target_wait_prop,
group = 1, colour = "Baseline"),
size = 1) +
geom_point(data = avg_wt_gt_12hrs_pre_covid, aes(x = month, y = target_wait_prop,
group = 1, colour = "Baseline")) +
theme_classic() +
scale_color_manual(name = "Year", values = c("Baseline" = "darkblue",
"2020" = "red",
"2021" = "green",
"2022" = "orange")) +
scale_y_continuous(labels = scales::percent) +
labs(y = "Percentage of admissions (%)",
title = "Proportion of waiting times greater than 12 hours",
subtitle = "Pre-covid (2007-2019) vs covid (2020+)",
col = "Year") +
theme(axis.title.x = element_blank(),
axis.text.x = element_text(angle = 45, hjust = 1))
Jack’s question:
beds_treatment_specialty <- beds
df1 <- beds_treatment_specialty %>% #pre covid dates, all health baords
mutate(date = yq(quarter), month = month(date, label = TRUE, abbr = TRUE),
year = year(date)) %>%
filter(year <= 2019, hb == "S08000015") %>% # hb selected by user input
group_by(month) %>%
summarise(avg_occupancy = mean(percentage_occupancy, na.rm = TRUE))
df2 <- beds_treatment_specialty %>%
mutate(date = yq(quarter), month = month(date, label = TRUE, abbr = TRUE),
year = year(date)) %>%
filter(year > 2019, hb == "S08000015") %>% #post covid, filter based on map input
group_by(year, month) %>%
summarise(avg_occupancy = mean(percentage_occupancy, na.rm = TRUE))
## no longer required
# df3 <- df1 %>%
# mutate(Type = "baseline") %>%
# bind_rows(df2 %>%
# mutate(Type = "post-covid"))
df2 %>%
ggplot(aes(x = month, y = avg_occupancy, colour = factor(year), group = year)) +
geom_point() +
geom_line() +
geom_line(data = df1, aes(x = month, y = avg_occupancy, group = 1, col = "Baseline")) +
geom_point(data = df1, aes(x = month, y = avg_occupancy, group = 1, col = "Baseline")) +
scale_color_manual(name = "Year", values = c("Baseline" = "darkblue",
"2020" = "red",
"2021" = "green")) +
labs(title = "Avg Occupancy by Health Board vs Baseline", # need to update these
x = "Month",
y = "Avg Occupancy Rate")
df2_wide <- df2 %>%
pivot_wider(names_from = year, values_from = avg_occupancy)
df12 <- df1 %>%
rename(baseline = avg_occupancy) %>%
left_join(df2_wide, "month")
df12
df3 <- beds_treatment_specialty %>% #pre covid dates, all health baords
mutate(date = yq(quarter), month = month(date, label = TRUE, abbr = TRUE),
year = year(date)) %>%
filter(year <= 2019, hb == "S08000015") %>% # hb selected by user input
group_by(month) %>%
summarise(total_available = sum(all_staffed_beddays),
total_occupied = sum(total_occupied_beddays),
avg_occupancy = total_occupied / total_available)
df4 <- beds_treatment_specialty %>%
mutate(date = yq(quarter), month = month(date, label = TRUE, abbr = TRUE),
year = year(date)) %>%
filter(year > 2019, hb == "S08000015") %>% #post covid, filter based on map input
group_by(year, month) %>%
summarise(total_available = sum(all_staffed_beddays),
total_occupied = sum(total_occupied_beddays),
avg_occupancy = total_occupied / total_available)
df4 %>%
ggplot(aes(x = month, y = avg_occupancy, colour = factor(year), group = year)) +
geom_point() +
geom_line() +
geom_line(data = df3, aes(x = month, y = avg_occupancy, group = 1, col = "Baseline")) +
geom_point(data = df3, aes(x = month, y = avg_occupancy, group = 1, col = "Baseline")) +
scale_color_manual(name = "Year", values = c("Baseline" = "darkblue",
"2020" = "red",
"2021" = "green")) +
labs(title = "Avg Occupancy by Health Board vs Baseline", # need to update these
x = "Month",
y = "Avg Occupancy Rate") +
scale_y_continuous(labels = scales::percent)
df4_wide <- df2 %>%
pivot_wider(names_from = year, values_from = avg_occupancy)
df34 <- df3 %>%
rename(baseline = avg_occupancy) %>%
left_join(df2_wide, "month") %>%
select(-total_available, - total_occupied) %>%
mutate(baseline = baseline * 100)
# weighted average occupancy rate
df34
# average of occupancy percentages
df12
how does bed usage change over time
beds %>%
group_by(quarter) %>%
summarise(beds_available = sum(all_staffed_beddays),
beds_occupied = sum(total_occupied_beddays)) %>%
pivot_longer(beds_available:beds_occupied, names_to = "bed_type",
values_to = "num_beds") %>%
ggplot(aes(x = quarter, y = num_beds, colour = bed_type, group = bed_type)) +
geom_line() +
scale_y_continuous(labels = scales::comma) +
theme_classic() +
theme(axis.text = element_text(angle = 45, hjust = 1),
axis.title.x = element_blank()) +
labs(y = "Number of bed days",
title = "Number of beds available/occupied over time",
col = "Bed Type")
bed use by specialty
beds %>%
group_by(quarter, specialty_name) %>%
# filter(specialty_name %in% c("Clinical Radiology", "Intensive Care Medicine")) %>%
summarise(beds_available = sum(all_staffed_beddays),
beds_occupied = sum(total_occupied_beddays)) %>%
pivot_longer(beds_available:beds_occupied, names_to = "bed_type",
values_to = "num_beds") %>%
ggplot(aes(x = quarter, y = num_beds, colour = specialty_name, group = specialty_name)) +
geom_line() +
facet_wrap(~bed_type) +
scale_y_continuous(labels = scales::comma) +
theme_classic() +
theme(axis.text = element_text(angle = 45, hjust = 1),
axis.title.x = element_blank()) +
labs(y = "Number of bed days",
title = "Number of beds available/occupied over time",
col = "Bed Type")
beds %>%
mutate(year = as.numeric(str_extract(quarter, "[0-9]{4}")),
is_covid_year = case_when(
year <= 2019 ~ FALSE,
year >= 2020 ~ TRUE
)) %>%
group_by(specialty_name, is_covid_year) %>%
summarise(beds_available = sum(all_staffed_beddays),
beds_occupied = sum(total_occupied_beddays)) %>%
select(specialty_name, is_covid_year, beds_occupied) %>%
pivot_wider(names_from = is_covid_year, values_from = beds_occupied) %>%
rename("pre_covid" = "FALSE", "covid" = "TRUE") %>%
drop_na() %>%
mutate(diff_occupied = covid - pre_covid,
diff_occupied_pc = ((covid / pre_covid) - 1) * 100) %>%
filter(diff_occupied_pc > 0) %>%
arrange(desc(diff_occupied_pc))
waiting times
cleaning
hb <- read_csv(here("clean_data/hb_list_simple.csv"))
waiting_times <- waiting_times_raw %>%
mutate(date_ym = ym(month), .before = month,
month = month(date_ym, label = TRUE, abbr = FALSE),
year = year(date_ym)) %>%
left_join(hb, c("hbt" = "hb")) %>%
left_join(hospitals, c("treatment_location" = "location")) %>%
rename(total_attendance = number_of_attendances_aggregate,
wait_lt_4hrs = number_meeting_target_aggregate,
wait_gt_8hrs = attendance_greater8hrs,
wait_gt_12hrs = attendance_greater12hrs,
hospital_id = treatment_location,
hospital_name = location_name) %>%
select(date_ym, year, month, hb_name, hospital_id, hospital_name, department_type,
total_attendance, wait_lt_4hrs, wait_gt_8hrs, wait_gt_12hrs) %>%
mutate(wait_gt_4hrs = total_attendance - wait_lt_4hrs, .after = wait_lt_4hrs) %>%
mutate(across(total_attendance:wait_gt_12hrs, .fns = ~coalesce(., 0)))
analysis
waiting_times %>%
mutate(is_covid_year = case_when(
year <= 2019 ~ FALSE,
year >= 2020 ~ TRUE
)) %>%
group_by(is_covid_year) %>%
summarise(sum_attendance = sum(total_attendance),
wait_target = sum(wait_lt_4hrs)) %>%
pivot_longer(wait_target, names_to = "wait_time", values_to = "value") %>%
mutate(proportion = value / sum_attendance) %>%
ggplot(aes(ymax = proportion, ymin = 0, xmax = 2, xmin = 1, fill = proportion)) +
geom_rect(aes(ymax = 1, ymin = 0, xmax = 2, xmin = 1), fill = "grey80") +
geom_rect() +
coord_polar(theta = "y",start=-pi/2) + xlim(c(0, 2)) + ylim(c(0,2)) +
geom_text(aes(x = 0, y = 0, label = scales::percent(proportion, accuracy = 0.1)), size = 6.5) +
geom_text(aes(x = 0.5, y = 1.5), label = c("Pre-Covid", "During Covid"), family="Poppins Light", size=4.2) +
facet_wrap(~is_covid_year, nrow = 1) +
theme_void() +
# scale_fill_manual(values = c("red"="#C9146C", "orange"="#DA9112", "green"="#129188")) +
scale_colour_manual(values = c("red"="#C9146C", "orange"="#DA9112", "green"="#129188")) +
theme(strip.background = element_blank(),
strip.text.x = element_blank(),
legend.position = "none") +
# ,
# +
labs(title = " Percentage of admissions achieving target wait times (<4hrs)")
library(ggforce)
library(scales)
waiting_times %>%
mutate(is_covid_year = case_when(
year <= 2019 ~ FALSE,
year >= 2020 ~ TRUE
)) %>%
group_by(is_covid_year) %>%
summarise(sum_attendance = sum(total_attendance),
wait_target = sum(wait_lt_4hrs)) %>%
pivot_longer(wait_target, names_to = "wait_time", values_to = "value") %>%
mutate(proportion = value / sum_attendance) %>%
mutate(ymin = rescale(0, to = pi*c(-.5,.5), from = 0:1),
ymax = rescale(proportion, to = pi*c(-.5,.5), from = 0:1)) %>%
ggplot(aes(x0 = 0, y0 = 0, r0 = .5, r = 1)) +
geom_arc_bar(aes(start = - pi / 2, end = pi / 2), fill = "grey80") +
geom_arc_bar(aes(x0 = 0, y0 = 0, r0 = .5, r = 1, start = ymin, end = ymax, fill = proportion)) +
coord_fixed() +
facet_wrap(~ is_covid_year) +
ylim(-0.3, 1) +
geom_text(aes(x = 0, y = 0.01, label = scales::percent(proportion, accuracy = 0.1)), size = 6.5) +
geom_text(aes(x = 0, y = -0.25), label = c("Pre-Covid", "During Covid"), family= "Poppins Light", size=4.2) +
theme_void() +
theme(strip.background = element_blank(),
strip.text = element_blank(),
legend.position = "none",
title = element_text(vjust = 1),
plot.margin = unit(c(0, 0, 0, 0), "cm")) +
labs(title = " Percentage of admissions achieving target wait times (<4hrs)\n")
Colour palette
pal <- c(rgb(199, 175, 117, maxColorValue = 255),
rgb(124, 36, 24, maxColorValue = 255),
rgb(210, 221, 213, maxColorValue = 255),
rgb(168, 106, 57, maxColorValue = 255),
rgb(222, 224, 227, maxColorValue = 255),
rgb(186, 158, 53, maxColorValue = 255),
rgb(6, 57, 83, maxColorValue = 255),
rgb(109, 67, 85, maxColorValue = 255)
)
show_col(pal)
Rob’s problem
inpatient_and_daycase_by_nhs_board_of_treatment_and_simd_non_covid_cleaned %>%
select(quarter_year, year, hb_name, simd, admission_type, stays, is_covid_year) %>%
filter(stays >0) %>%
filter(hb_name != “”) %>%
Error: unexpected input in:
" filter(stays >0) %>%
filter(hb_name != “"
health_board_map %>%
plot_geo(locationmode = "Scotland") %>%
add_trace(text = ~hb_name)
No scattergeo mode specifed:
Setting the mode to markers
Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
No scattergeo mode specifed:
Setting the mode to markers
Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIExvYWQgaW4gbGlicmFyaWVzDQpgYGB7cn0NCg0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGhlcmUpDQpsaWJyYXJ5KGphbml0b3IpDQpsaWJyYXJ5KHRzaWJibGUpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoc2YpDQoNCmBgYA0KIyBMb2FkIGluIGRhdGEgc2V0cw0KYGBge3J9DQoNCndhaXRpbmdfdGltZXNfcmF3IDwtIHJlYWRfY3N2KGhlcmUoInJhd19kYXRhL25vbl9jb3ZpZC9tb250aGx5X2FlX3dhaXRpbmd0aW1lc18yMDIyMDYuY3N2IikpICU+JSANCiAgY2xlYW5fbmFtZXMoKQ0KDQpoYiA8LSByZWFkX2NzdihoZXJlKCJjbGVhbl9kYXRhL2hiX2xpc3Rfc2ltcGxlLmNzdiIpKQ0KDQpob3NwaXRhbHMgPC0gcmVhZF9jc3YoaGVyZSgicmF3X2RhdGEvZ2VuZXJhbC9jdXJyZW50LWhvc3BpdGFsX2ZsYWdnZWQyMDIxMTIxNi5jc3YiKSkgJT4lIA0KICBjbGVhbl9uYW1lcygpICU+JSANCiAgc2VsZWN0KGxvY2F0aW9uLCBsb2NhdGlvbl9uYW1lKQ0KDQpgYGANCg0KIyBjbGVhbiBkYXRhc2V0DQoNClRoZSBmb2xsb3dpbmcgY2xlYW5pbmcgZG9lcyB0aGUgZm9sbG93aW5nIHRvIHRoZSB3YWl0aW5nIHRpbWVzIGRhdGEgc2V0OiANCi0gY29udmVydHMgbW9udGggY29sdW1uIHRvIHllYXJfbW9udGggZGF0ZXMgYW5kIGV4dHJhY3RzIHllYXJzIGFuZCBtb250aHMgIA0KLSBqb2lucyBoZWFsdGggYm9hcmQgYW5kIGhvc3BpdGFsIG5hbWVzIHRvIGRhdGEgc2V0ICANCi0gcmVuYW1lcyBjb2x1bW5zIHRvIG1vcmUgZWFzaWx5IHVuZGVyc3RhbmRhYmxlIG5hbWVzICANCi0gcmVtb3ZlcyBjb2x1bW5zIHJlbGF0aW5nIHRvICJlcGlzb2RlcyIsICJxdWFsaWZpZXIgY29kZXMiIGFuZCAiZGlzY2hhcmdlcyINCi0gYWRkcyBuZXcgdmFsdWUgb2Ygd2FpdCBncmVhdGVyIHRoYW4gNCBob3VycyB0byB0aGUgZGF0YSAgDQotIF9yZXBsYWNlcyBhbGwgTkEgdmFsdWVzIHdpdGggMCAodGhpcyBzdGVwIG1heSBiZSBvcHRpb25hbClfDQoNClBsZWFzZSBub3RlIHRoYXQgNCBob3VycyB3YWl0IHRpbWUgaXMgdGhlICJUYXJnZXQiIHdhaXQgdGltZSBmb3IgdGhlIE5IUyBhbmQgaXMNCnJlcHJlc2VudGVkIGJ5IHRoZSAid2FpdF9sdF80aHJzIiBjb2x1bW4gdmFsdWVzLg0KYGBge3J9DQojIGNsZWFuaW5nIHNjcmlwdA0Kd2FpdGluZ190aW1lcyA8LSB3YWl0aW5nX3RpbWVzX3JhdyAlPiUgDQogIG11dGF0ZShkYXRlX3ltID0geW0obW9udGgpLCAuYmVmb3JlID0gbW9udGgsDQogICAgICAgICBtb250aCA9IG1vbnRoKGRhdGVfeW0sIGxhYmVsID0gVFJVRSwgYWJiciA9IEZBTFNFKSwNCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGVfeW0pKSAlPiUgDQogIGxlZnRfam9pbihoYiwgYygiaGJ0IiA9ICJoYiIpKSAlPiUgDQogIGxlZnRfam9pbihob3NwaXRhbHMsIGMoInRyZWF0bWVudF9sb2NhdGlvbiIgPSAibG9jYXRpb24iKSkgJT4lIA0KICByZW5hbWUodG90YWxfYXR0ZW5kYW5jZSA9IG51bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUsDQogICAgICAgICB3YWl0X2x0XzRocnMgPSBudW1iZXJfbWVldGluZ190YXJnZXRfYWdncmVnYXRlLA0KICAgICAgICAgd2FpdF9ndF84aHJzID0gYXR0ZW5kYW5jZV9ncmVhdGVyOGhycywNCiAgICAgICAgIHdhaXRfZ3RfMTJocnMgPSBhdHRlbmRhbmNlX2dyZWF0ZXIxMmhycywNCiAgICAgICAgIGhvc3BpdGFsX2lkID0gdHJlYXRtZW50X2xvY2F0aW9uLCANCiAgICAgICAgIGhvc3BpdGFsX25hbWUgPSBsb2NhdGlvbl9uYW1lKSAlPiUNCiAgc2VsZWN0KGRhdGVfeW0sIHllYXIsIG1vbnRoLCBoYl9uYW1lLCBob3NwaXRhbF9pZCwgaG9zcGl0YWxfbmFtZSwgZGVwYXJ0bWVudF90eXBlLA0KICAgICAgICAgdG90YWxfYXR0ZW5kYW5jZSwgd2FpdF9sdF80aHJzLCB3YWl0X2d0XzhocnMsIHdhaXRfZ3RfMTJocnMpICU+JSANCiAgbXV0YXRlKHdhaXRfZ3RfNGhycyA9IHRvdGFsX2F0dGVuZGFuY2UgLSB3YWl0X2x0XzRocnMsIC5hZnRlciA9IHdhaXRfbHRfNGhycykgJT4lDQogIG11dGF0ZShhY3Jvc3ModG90YWxfYXR0ZW5kYW5jZTp3YWl0X2d0XzEyaHJzLCAuZm5zID0gfmNvYWxlc2NlKC4sIDApKSkNCg0Kd2FpdGluZ190aW1lcyA8LSByZWFkX2NzdihoZXJlKCJjbGVhbl9kYXRhL3dhaXRfdGltZXMuY3N2IikpICU+JSANCiAgbXV0YXRlKG1vbnRoID0gbW9udGgoZGF0ZV95bSwgbGFiZWwgPSBUUlVFLCBhYmJyID0gRkFMU0UpKSANCmBgYA0KDQpgYGB7cn0NCiMgY3JlYXRlIHRhYmxlIHdpdGggcHJvcG9ydGlvbnMgb2Ygd2FpdCB0aW1lcyB1c2VkIGZvciB0aGUgYW5hbHlzaXMNCndhaXRpbmdfdGltZXNfcHJvcCA8LSB3YWl0aW5nX3RpbWVzICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbnRhaW5zKCJ3YWl0IiksIG5hbWVzX3RvID0gIndhaXRfY2F0ZWdvcnkiLCB2YWx1ZXNfdG8gPSAibnVtYmVyX29mX2F0dGVuZGFuY2VzIikgJT4lIA0KICBtdXRhdGUod2FpdF9wcm9wID0gbnVtYmVyX29mX2F0dGVuZGFuY2VzIC8gdG90YWxfYXR0ZW5kYW5jZSwNCiAgICAgICAgIHdhaXRfY2F0ZWdvcnkgPSBzdHJfcmVwbGFjZSh3YWl0X2NhdGVnb3J5LCAid2FpdCIsICJwcm9wIikpICU+JSANCiAgc2VsZWN0KC1udW1iZXJfb2ZfYXR0ZW5kYW5jZXMpICU+JSANCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHdhaXRfY2F0ZWdvcnksIHZhbHVlc19mcm9tID0gd2FpdF9wcm9wKQ0KDQoNCndhaXRpbmdfdGltZXNfcHJvcA0KYGBgDQoNCiMgQW5hbHlzaXMNCg0KIyMgSG93IGRvZXMgaG9zcGl0YWwgYXR0ZW5kYW5jZXMgY2hhbmdlIHdpdGggdGltZT8NCg0KYGBge3J9DQojIHBsb3QgYWxsIGRhdGEgLSBhdHRlbmRhbmNlcyBwZXIgeWVhcg0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHRvdGFsX2F0dGVuZGFuY2UpKSArDQogIGdlb21fbGluZSgpDQoNCiMgYXR0ZW5kYW5jZXMgLSBhbGwgZGF0YSBjb3ZpZCBzZWFzb25hbCBhbmFseXNpcw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIsIG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdG90YWxfYXR0ZW5kYW5jZSwgZ3JvdXAgPSB5ZWFyLCBjb2wgPSBmYWN0b3IoeWVhcikpKSArDQogIGdlb21fbGluZSgpDQoNCiMgYXR0ZW5kYW5jZXMgcGVyIG1vbnRoIC0gcHJlLWNvdmlkIHNlYXNvbmFsIGFuYWx5c2lzDQp3YWl0aW5nX3RpbWVzICU+JSANCiAgZmlsdGVyKHllYXIgPCAyMDIwKSAlPiUgDQogIGdyb3VwX2J5KHllYXIsIG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdG90YWxfYXR0ZW5kYW5jZSwgZ3JvdXAgPSB5ZWFyLCBjb2wgPSBmYWN0b3IoeWVhcikpKSArDQogIGdlb21fbGluZSgpDQoNCiMgYXR0ZW5kYW5jZXMgcGVyIG1vbnRoIC0gY292aWQgc2Vhc29uYWwgYW5hbHlzaXMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBmaWx0ZXIoeWVhciA+PSAyMDIwKSAlPiUgDQogIGdyb3VwX2J5KHllYXIsIG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdG90YWxfYXR0ZW5kYW5jZSwgZ3JvdXAgPSB5ZWFyLCBjb2wgPSBmYWN0b3IoeWVhcikpKSArDQogIGdlb21fbGluZSgpDQoNCmBgYA0KDQpgYGB7cn0NCg0KaGVhbHRoX2JvYXJkX2lucHV0IDwtIGMoIkJvcmRlcnMiLCAiTG90aGlhbiIsICJBeXJzaGlyZSBhbmQgQXJyYW4iLCAiRHVtZnJpZXMgYW5kIEdhbGxvd2F5IikNCg0KIyBoZWFsdGhfYm9hcmRfaW5wdXQgPC0gaGIkaGJfbmFtZQ0KDQpwYXN0ZSgiTXVsdGlwbGUgSEI6XG4iLCBwYXN0ZShzb3J0KGhlYWx0aF9ib2FyZF9pbnB1dCksIGNvbGxhcHNlID0gIiwgIiksIHNlcCA9ICJcbiIpDQoNCnN0cl9jKCJNdWx0aXBsZSBIQnM6XG4iLCBzdHJfYygiQm9yZGVycyIsICJMb3RoaWFuIiwgIkR1bWZyaWVzIiwgc2VwID0gIixcbiIpKQ0KDQojIHBsb3QgYWxsIGRhdGEgLSBhdHRlbmRhbmNlcyBwZXIgeWVhcg0KDQogIA0KICBpZihsZW5ndGgoaGVhbHRoX2JvYXJkX2lucHV0KSA8PSAzKSB7DQogICANCiAgICAjZmlyc3QgdHdvIHJvd3Mgd2lsbCBiZSBmcm9tIHJlYWN0aXZlIGZ1bmN0aW9uDQogICAgcCA8LSB3YWl0aW5nX3RpbWVzICU+JSANCiAgICAgIGZpbHRlcihoYl9uYW1lICVpbiUgaGVhbHRoX2JvYXJkX2lucHV0KSAlPiUgDQogICAgICBncm91cF9ieShkYXRlX3ltLCBoYl9uYW1lKSAlPiUgDQogICAgICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSkgJT4lIA0KICAgICAgZ2dwbG90KGFlcyh4ID0gZGF0ZV95bSwgeSA9IHRvdGFsX2F0dGVuZGFuY2UsIGNvbCA9IGhiX25hbWUpKSArDQogICAgICBnZW9tX2xpbmUoKQ0KDQogIH0gZWxzZSB7DQogICAgDQogICAgaWYobGVuZ3RoKGhlYWx0aF9ib2FyZF9pbnB1dCkgPT0gMTQpIHsNCiAgICAgIGhiX2xhYmVsIDwtICJBbGwgSGVhbHRoIEJvYXJkcyINCiAgICB9IGVsc2Ugew0KICAgICAgaGJfbGFiZWwgPC0gc3RyX2MoIlRvdGFsIG9mIE11bHRpcGxlIEhCczpcbiIsDQogICAgICAgICAgICAgICAgICAgICAgICBzdHJfYyhoZWFsdGhfYm9hcmRfaW5wdXQsIGNvbGxhcHNlID0gIixcbiIpKQ0KICAgIH0NCiANCiAgICBwIDwtIHdhaXRpbmdfdGltZXMgJT4lIA0KICAgICAgZmlsdGVyKGhiX25hbWUgJWluJSBoZWFsdGhfYm9hcmRfaW5wdXQpICU+JSANCiAgICAgIG11dGF0ZShoYl9sYWJlbCA9IGhiX2xhYmVsKSAlPiUgDQogICAgICBncm91cF9ieShkYXRlX3ltKSAlPiUgDQogICAgICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSkgJT4lIA0KICAgICAgZ2dwbG90KGFlcyh4ID0gZGF0ZV95bSwgeSA9IHRvdGFsX2F0dGVuZGFuY2UsIGNvbG91ciA9IGhiX2xhYmVsKSkgKw0KICAgICAgZ2VvbV9saW5lKCkNCiAgICANCiAgfQ0KDQpwICArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBjb21tYSwgDQogICAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKDAsIDApLA0KICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygwLCBOQSkpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiVZIiwNCiAgICAgICAgICAgICAgIGRhdGVfYnJlYWtzID0gIjEgeWVhciIpICsNCiAgbGFicyh0aXRsZSA9ICJUb3RhbCBob3NwaXRhbCBhdHRlbmRhbmNlcyIsDQogICAgICAgc3VidGl0bGUgPSAiSnVseSAyMDA3IHRvIEp1bmUgMjAyMiIsIA0KICAgICAgIGNvbCA9ICJIZWFsdGggQm9hcmQiLA0KICAgICAgIHkgPSAiVG90YWwgYXR0ZW5kYW5jZXMiKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgbGVnZW5kLnRleHQuYWxpZ24gPSAwKQ0KDQpgYGANCg0KDQojIEhvdyBkbyB3YWl0IHRpbWVzIGNoYW5nZSBwZXIgeWVhcj8gKGluIHRlcm1zIG9mIG51bWJlcnMpDQoNCmBgYHtyfQ0KIyB3YWl0IHRpbWVzIGxlc3MgdGhhbiA0IGhvdXJzDQp3YWl0aW5nX3RpbWVzICU+JSANCiAgZ3JvdXBfYnkoeWVhcikgJT4lIA0KICBzdW1tYXJpc2Uod2FpdF9sdF80aHJzID0gc3VtKHdhaXRfbHRfNGhycykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHdhaXRfbHRfNGhycykpICsNCiAgZ2VvbV9jb2woKQ0KDQojIHdhaXQgdGltZXMgbW9yZSB0aGFuIDQgaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyKSAlPiUgDQogIHN1bW1hcmlzZSh3YWl0X2d0XzRocnMgPSBzdW0od2FpdF9ndF80aHJzKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gd2FpdF9ndF80aHJzKSkgKw0KICBnZW9tX2NvbCgpDQoNCiMgd2FpdCB0aW1lcyBtb3JlIHRoYW4gOCBob3Vycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIpICU+JSANCiAgc3VtbWFyaXNlKHdhaXRfZ3RfOGhycyA9IHN1bSh3YWl0X2d0XzhocnMpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSB3YWl0X2d0XzhocnMpKSArDQogIGdlb21fY29sKCkNCg0KIyB3YWl0IHRpbWVzIG1vcmUgdGhhbiAxMiBob3Vycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIpICU+JSANCiAgc3VtbWFyaXNlKHdhaXRfZ3RfMTJocnMgPSBzdW0od2FpdF9ndF8xMmhycykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHdhaXRfZ3RfMTJocnMpKSArDQogIGdlb21fY29sKCkNCg0KYGBgDQoNCiMgSG93IGRvIHdhaXQgdGltZXMgY2hhbmdlIHBlciB5ZWFyPyAoaW4gdGVybXMgb2YgcHJvcG9ydGlvbikNCg0KYGBge3J9DQoNCiMgd2FpdCB0aW1lcyBsZXNzIHRoYW4gNCBob3Vycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICB3YWl0X2x0XzRocnMgPSBzdW0od2FpdF9sdF80aHJzKSwNCiAgICAgICAgICAgIHByb3BfbHRfNGhycyA9IHdhaXRfbHRfNGhycyAvIHRvdGFsX2F0dGVuZGFuY2UpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHByb3BfbHRfNGhycykpICsNCiAgZ2VvbV9jb2woKQ0KDQojIHdhaXQgdGltZXMgbW9yZSB0aGFuIDQgaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpLA0KICAgICAgICAgICAgd2FpdF9ndF80aHJzID0gc3VtKHdhaXRfZ3RfNGhycyksDQogICAgICAgICAgICBwcm9wX2d0XzRocnMgPSB3YWl0X2d0XzRocnMgLyB0b3RhbF9hdHRlbmRhbmNlKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBwcm9wX2d0XzRocnMpKSArDQogIGdlb21fY29sKCkNCg0KIyB3YWl0IHRpbWVzIG1vcmUgdGhhbiA4IGhvdXJzDQp3YWl0aW5nX3RpbWVzICU+JSANCiAgZ3JvdXBfYnkoeWVhcikgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHdhaXRfZ3RfOGhycyA9IHN1bSh3YWl0X2d0XzhocnMpLA0KICAgICAgICAgICAgcHJvcF9ndF84aHJzID0gd2FpdF9ndF84aHJzIC8gdG90YWxfYXR0ZW5kYW5jZSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcHJvcF9ndF84aHJzKSkgKw0KICBnZW9tX2NvbCgpDQoNCiMgd2FpdCB0aW1lcyBtb3JlIHRoYW4gMTIgaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpLA0KICAgICAgICAgICAgd2FpdF9ndF8xMmhycyA9IHN1bSh3YWl0X2d0XzEyaHJzKSwNCiAgICAgICAgICAgIHByb3BfZ3RfMTJocnMgPSB3YWl0X2d0XzEyaHJzIC8gdG90YWxfYXR0ZW5kYW5jZSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcHJvcF9ndF8xMmhycykpICsNCiAgZ2VvbV9jb2woKSArDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsMCksDQogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSArDQogIGxhYnMoeSA9ICJQZXJjZW50YWdlIG9mIGF0dGVuZGFuY2VzIGdyZWF0ZXIgdGhhbiAxMiBob3VycyIsDQogICAgICAgdGl0bGUgPSAiV2FpdCB0aW1lcyBvZiA+MTJob3VycyBlYWNoIHllYXIiKQ0KDQpgYGANCiMgSG93IGRvIHdhaXQgdGltZXMgZGlmZmVyIGJldHdlZW4gZGVwYXJ0bWVudHM/IChpbiB0ZXJtcyBvZiBwcm9wb3J0aW9ucykNCg0KYGBge3J9DQoNCiMgd2FpdCB0aW1lcyBsZXNzIHRoYW4gNCBob3Vycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIsIGRlcGFydG1lbnRfdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHdhaXRfbHRfNGhycyA9IHN1bSh3YWl0X2x0XzRocnMpLA0KICAgICAgICAgICAgcHJvcF9sdF80aHJzID0gd2FpdF9sdF80aHJzIC8gdG90YWxfYXR0ZW5kYW5jZSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcHJvcF9sdF80aHJzLCBmaWxsID0gZGVwYXJ0bWVudF90eXBlKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQoNCiMgd2FpdCB0aW1lcyBtb3JlIHRoYW4gNCBob3Vycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIsIGRlcGFydG1lbnRfdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHdhaXRfZ3RfNGhycyA9IHN1bSh3YWl0X2d0XzRocnMpLA0KICAgICAgICAgICAgcHJvcF9ndF80aHJzID0gd2FpdF9ndF80aHJzIC8gdG90YWxfYXR0ZW5kYW5jZSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcHJvcF9ndF80aHJzLCBmaWxsID0gZGVwYXJ0bWVudF90eXBlKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQoNCiMgd2FpdCB0aW1lcyBtb3JlIHRoYW4gOCBob3Vycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIsIGRlcGFydG1lbnRfdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHdhaXRfZ3RfOGhycyA9IHN1bSh3YWl0X2d0XzhocnMpLA0KICAgICAgICAgICAgcHJvcF9ndF84aHJzID0gd2FpdF9ndF84aHJzIC8gdG90YWxfYXR0ZW5kYW5jZSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcHJvcF9ndF84aHJzLCBmaWxsID0gZGVwYXJ0bWVudF90eXBlKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQoNCiMgd2FpdCB0aW1lcyBtb3JlIHRoYW4gMTIgaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyLCBkZXBhcnRtZW50X3R5cGUpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICB3YWl0X2d0XzEyaHJzID0gc3VtKHdhaXRfZ3RfMTJocnMpLA0KICAgICAgICAgICAgcHJvcF9ndF8xMmhycyA9IHdhaXRfZ3RfMTJocnMgLyB0b3RhbF9hdHRlbmRhbmNlKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBwcm9wX2d0XzEyaHJzLCBmaWxsID0gZGVwYXJ0bWVudF90eXBlKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQoNCmBgYA0KDQojIEhvdyBkbyB3YWl0IHRpbWVzIGNoYW5nZSBwZXIgeWVhciAmIG1vbnRoPyAoaW4gdGVybXMgb2YgbnVtYmVycykNCg0KYGBge3J9DQojIHdhaXQgdGltZXMgbGVzcyB0aGFuIDQgaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyLCBtb250aCkgJT4lIA0KICBzdW1tYXJpc2Uod2FpdF9sdF80aHJzID0gc3VtKHdhaXRfbHRfNGhycykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB3YWl0X2x0XzRocnMsIGdyb3VwID0geWVhciwgY29sID0gZmFjdG9yKHllYXIpKSkgKw0KICBnZW9tX2xpbmUoKQ0KDQojIHdhaXQgdGltZXMgbW9yZSB0aGFuIDQgaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyLCBtb250aCkgJT4lIA0KICBzdW1tYXJpc2Uod2FpdF9ndF80aHJzID0gc3VtKHdhaXRfZ3RfNGhycykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB3YWl0X2d0XzRocnMsIGdyb3VwID0geWVhciwgY29sID0gZmFjdG9yKHllYXIpKSkgKw0KICBnZW9tX2xpbmUoKQ0KDQojIHdhaXQgdGltZXMgbW9yZSB0aGFuIDggaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyLCBtb250aCkgJT4lIA0KICBzdW1tYXJpc2Uod2FpdF9ndF84aHJzID0gc3VtKHdhaXRfZ3RfOGhycykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB3YWl0X2d0XzhocnMsIGdyb3VwID0geWVhciwgY29sID0gZmFjdG9yKHllYXIpKSkgKw0KICBnZW9tX2xpbmUoKQ0KDQojIHdhaXQgdGltZXMgbW9yZSB0aGFuIDEyIGhvdXJzDQp3YWl0aW5nX3RpbWVzICU+JSANCiAgZ3JvdXBfYnkoeWVhciwgbW9udGgpICU+JSANCiAgc3VtbWFyaXNlKHdhaXRfZ3RfMTJocnMgPSBzdW0od2FpdF9ndF8xMmhycykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB3YWl0X2d0XzEyaHJzLCBncm91cCA9IHllYXIsIGNvbCA9IGZhY3Rvcih5ZWFyKSkpICsNCiAgZ2VvbV9saW5lKCkNCg0KYGBgDQoNCiMgSG93IGRvIHdhaXQgdGltZXMgdmFyeSBhY3Jvc3MgaGVhbHRoIGJvYXJkcz8NCg0KYGBge3J9DQojIGluIHRlcm1zIG9mIG51bWJlcnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieShkYXRlX3ltLCBoZWFsdGhfYm9hcmQpICU+JSANCiAgc3VtbWFyaXNlKHdhaXRfZ3RfOGhycyA9IHN1bSh3YWl0X2d0XzhocnMpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGRhdGVfeW0sIHkgPSB3YWl0X2d0XzhocnMsIGNvbCA9IGhlYWx0aF9ib2FyZCkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIk51bWJlciBvZiB3YWl0cyA+IDggaG91cnMgZm9yIGVhY2ggaGVhbHRoYm9hcmQiKQ0KDQojIGluIHRlcm1zIG9mIHByb3BvcnRpb24NCndhaXRpbmdfdGltZXNfcHJvcCAlPiUgDQogIGdyb3VwX2J5KGRhdGVfeW0sIGhlYWx0aF9ib2FyZCkgJT4lIA0KICBzdW1tYXJpc2UocHJvcF9ndF84aHJzID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UgKiBwcm9wX2d0XzhocnMpLw0KICAgICAgICAgICAgICBzdW0odG90YWxfYXR0ZW5kYW5jZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZV95bSwgeSA9IHByb3BfZ3RfOGhycywgY29sID0gaGVhbHRoX2JvYXJkKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGxhYnModGl0bGUgPSAiUHJvcG9ydGlvbiBvZiB3YWl0cyA+IDggaG91cnMgZm9yIGVhY2ggaGVhbHRoYm9hcmQiKQ0KDQoNCiMgZmluZCB0b3AgNSBoZWFsdGhib2FyZHMgKGluIHRlcm1zIG9mIGF0dGVuZGFuY2VzKQ0KdG9wXzVfYXR0ZW5kYW5jZXNfYnlfaGIgPC0gd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgZ3JvdXBfYnkoaGVhbHRoX2JvYXJkKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHQgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSkpICU+JSANCiAgc2xpY2VfbWF4KHRvdGFsX2F0dCwgbiA9IDUpDQoNCiMgZmluZCBib3R0b20gNSBoZWFsdGhib2FyZHMgKGluIHRlcm1zIG9mIGF0dGVuZGFuY2VzKQ0KYm90dG9tXzVfYXR0ZW5kYW5jZXNfYnlfaGIgPC0gd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgZ3JvdXBfYnkoaGVhbHRoX2JvYXJkKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHQgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSkpICU+JSANCiAgc2xpY2VfbWluKHRvdGFsX2F0dCwgbiA9IDUpDQoNCiMgd2FpdCB0aW1lcyBhY3Jvc3MgdGhlIHRvcCA1IGhlYWx0aGJvYXJkcyA+IDggaG91cnMNCndhaXRpbmdfdGltZXNfcHJvcCAlPiUgDQogIGZpbHRlcihoZWFsdGhfYm9hcmQgJWluJSB0b3BfNV9hdHRlbmRhbmNlc19ieV9oYiRoZWFsdGhfYm9hcmQpICU+JSANCiAgZ3JvdXBfYnkoZGF0ZV95bSwgaGVhbHRoX2JvYXJkKSAlPiUgDQogIHN1bW1hcmlzZShwcm9wX2d0XzhocnMgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSAqIHByb3BfZ3RfOGhycykvDQogICAgICAgICAgICAgIHN1bSh0b3RhbF9hdHRlbmRhbmNlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkYXRlX3ltLCB5ID0gcHJvcF9ndF84aHJzLCBjb2wgPSBoZWFsdGhfYm9hcmQpKSArDQogIGdlb21fbGluZSgpICsNCiAgbGFicyh0aXRsZSA9ICJQcm9wb3J0aW9uIG9mIHdhaXRzID4gOCBob3VycyBmb3IgdGhlIHRvcCA1IG1vc3QgYXR0ZW5kZWQgaGVhbHRoYm9hcmRzIikNCg0KIyB3YWl0IHRpbWVzIGFjcm9zcyB0aGUgYm90dG9tIDUgaGVhbHRoYm9hcmRzID4gOCBob3Vycw0Kd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgZmlsdGVyKGhlYWx0aF9ib2FyZCAlaW4lIGJvdHRvbV81X2F0dGVuZGFuY2VzX2J5X2hiJGhlYWx0aF9ib2FyZCkgJT4lIA0KICBncm91cF9ieShkYXRlX3ltLCBoZWFsdGhfYm9hcmQpICU+JSANCiAgc3VtbWFyaXNlKHByb3BfZ3RfOGhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9ndF84aHJzKS8NCiAgICAgICAgICAgICAgc3VtKHRvdGFsX2F0dGVuZGFuY2UpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGRhdGVfeW0sIHkgPSBwcm9wX2d0XzhocnMsIGNvbCA9IGhlYWx0aF9ib2FyZCkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIlByb3BvcnRpb24gb2Ygd2FpdHMgPiA4IGhvdXJzIGZvciB0aGUgYm90dG9tIDUgbW9zdCBhdHRlbmRlZCBoZWFsdGhib2FyZHMiKQ0KDQoNCiMgd2FpdCB0aW1lcyBhY3Jvc3MgdGhlIHRvcCA1IGhlYWx0aGJvYXJkcyA+IDEyIGhvdXJzDQp3YWl0aW5nX3RpbWVzX3Byb3AgJT4lIA0KICBmaWx0ZXIoaGVhbHRoX2JvYXJkICVpbiUgdG9wXzVfYXR0ZW5kYW5jZXNfYnlfaGIkaGVhbHRoX2JvYXJkKSAlPiUgDQogIGdyb3VwX2J5KGRhdGVfeW0sIGhlYWx0aF9ib2FyZCkgJT4lIA0KICBzdW1tYXJpc2UocHJvcF9ndF8xMmhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9ndF8xMmhycykvDQogICAgICAgICAgICAgIHN1bSh0b3RhbF9hdHRlbmRhbmNlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkYXRlX3ltLCB5ID0gcHJvcF9ndF8xMmhycywgY29sID0gaGVhbHRoX2JvYXJkKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGxhYnModGl0bGUgPSAiUHJvcG9ydGlvbiBvZiB3YWl0cyA+IDEyIGhvdXJzIGZvciB0aGUgYm90dG9tIDUgbW9zdCBhdHRlbmRlZCBoZWFsdGhib2FyZHMiKQ0KDQojIHdhaXQgdGltZXMgYWNyb3NzIHRoZSBib3R0b20gNSBoZWFsdGhib2FyZHMgPiAxMiBob3Vycw0Kd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgZmlsdGVyKGhlYWx0aF9ib2FyZCAlaW4lIGJvdHRvbV81X2F0dGVuZGFuY2VzX2J5X2hiJGhlYWx0aF9ib2FyZCkgJT4lIA0KICBncm91cF9ieShkYXRlX3ltLCBoZWFsdGhfYm9hcmQpICU+JSANCiAgc3VtbWFyaXNlKHByb3BfZ3RfMTJocnMgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSAqIHByb3BfZ3RfMTJocnMpLw0KICAgICAgICAgICAgICBzdW0odG90YWxfYXR0ZW5kYW5jZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZV95bSwgeSA9IHByb3BfZ3RfMTJocnMsIGNvbCA9IGhlYWx0aF9ib2FyZCkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIlByb3BvcnRpb24gb2Ygd2FpdHMgPiAxMiBob3VycyBmb3IgdGhlIGJvdHRvbSA1IG1vc3QgYXR0ZW5kZWQgaGVhbHRoYm9hcmRzIikNCg0KYGBgDQoNCmBgYHtyfQ0KDQojIHdhaXQgdGltZXMgYWNyb3NzIGVhY2ggaG9zcGl0YWwgaW4gdGhlIEJvcmRlcnMgaGVhbHRoYm9hcmQNCndhaXRpbmdfdGltZXNfcHJvcCAlPiUgDQogICMgZmlsdGVyKGhlYWx0aF9ib2FyZCA9PSAiTkhTIEJvcmRlcnMiKSAlPiUgDQogIGdyb3VwX2J5KGRhdGVfeW0sIGhvc3BpdGFsX25hbWUpICU+JSANCiAgc3VtbWFyaXNlKHByb3BfZ3RfOGhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9ndF84aHJzKS8NCiAgICAgICAgICAgICAgc3VtKHRvdGFsX2F0dGVuZGFuY2UpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGRhdGVfeW0sIHkgPSBwcm9wX2d0XzhocnMsIGNvbCA9IGhvc3BpdGFsX25hbWUpKSArDQogIGdlb21fbGluZSgpICsNCiAgbGFicyh0aXRsZSA9ICJQcm9wb3J0aW9uIG9mIHdhaXRzID4gOCBob3VycyBmb3IgdGhlIGJvdHRvbSA1IG1vc3QgYXR0ZW5kZWQgaGVhbHRoYm9hcmRzIikgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCmBgYA0KDQojIG1vc3QgYWZmZWN0ZWQgaGVhbHRoYm9hcmRzDQpgYGB7cn0NCiMgaW4gdGVybXMgb2YgcHJvcG9ydGlvbg0KdG9wXzVfaG9zcGl0YWxfcHJvcHMgPC0gd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgZ3JvdXBfYnkoaG9zcGl0YWxfbmFtZSkgJT4lIA0KICBzdW1tYXJpc2UobWF4X3Byb3AgPSBtYXgocHJvcF9ndF8xMmhycykpICU+JSANCiAgYXJyYW5nZShkZXNjKG1heF9wcm9wKSkgJT4lIA0KICBzbGljZV9tYXgobWF4X3Byb3AsIG4gPSA1KQ0KICANCiMgaW4gdGVybXMgb2YgbnVtYmVycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KGhvc3BpdGFsX25hbWUpICU+JSANCiAgc3VtbWFyaXNlKG1heF9wcm9wID0gbWF4KHdhaXRfZ3RfMTJocnMpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhtYXhfcHJvcCkpDQoNCmBgYA0KDQpgYGB7cn0NCg0KIyB3YWl0IHRpbWVzIGFjcm9zcyBlYWNoIGhvc3BpdGFsIGluIHRoZSBCb3JkZXJzIGhlYWx0aGJvYXJkDQp3YWl0aW5nX3RpbWVzX3Byb3AgJT4lIA0KICBmaWx0ZXIoaG9zcGl0YWxfbmFtZSAlaW4lIHRvcF81X2hvc3BpdGFsX3Byb3BzJGhvc3BpdGFsX25hbWUpICU+JSANCiAgZ3JvdXBfYnkoZGF0ZV95bSwgaG9zcGl0YWxfbmFtZSkgJT4lIA0KICBzdW1tYXJpc2UocHJvcF9ndF8xMmhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9ndF8xMmhycykvDQogICAgICAgICAgICAgIHN1bSh0b3RhbF9hdHRlbmRhbmNlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkYXRlX3ltLCB5ID0gcHJvcF9ndF8xMmhycywgY29sID0gaG9zcGl0YWxfbmFtZSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIlByb3BvcnRpb24gb2Ygd2FpdHMgPiA4IGhvdXJzIGZvciB0aGUgYm90dG9tIDUgbW9zdCBhdHRlbmRlZCBoZWFsdGhib2FyZHMiKQ0KDQpgYGANCiMjIEZvciB0aGUgeWVhcnMgMjAwNyB0byAyMDE5LCBwcm92aWRlIGEgc3VtbWFyeSBvZiB0aGUgZWZmZWN0cyBvZiB3YWl0IHRpbWVzIGF0IGRpZmZlcmVudCB0aW1lcyBvZiB0aGUgeWVhci4NCmBgYHtyfQ0KDQp3YWl0aW5nX3RpbWVzX3N1bW1hcnkgPC0gd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgZmlsdGVyKHllYXIgPD0gMjAxOSkgJT4lIA0KICBtdXRhdGUobW9udGggPSBmYWN0b3IobW9udGgsIGxldmVscyA9IGMoIkp1bHkiLCAiQXVndXN0IiwgIlNlcHRlbWJlciIsICJPY3RvYmVyIiwgIk5vdmVtYmVyIiwgIkRlY2VtYmVyIiwgIkphbnVhcnkiLCAiRmVicnVhcnkiLCAiTWFyY2giLCAiQXByaWwiLCAiTWF5IiwgIkp1bmUiKSkpICU+JSANCiAgZ3JvdXBfYnkobW9udGgpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZHMgPSBtZWFuKHRvdGFsX2F0dGVuZGFuY2UpLA0KICAgICAgICAgICAgcHJvcF9sdF80aHJzID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UgKiBwcm9wX2x0XzRocnMpLyBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICBwcm9wX2d0XzRocnMgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSAqIHByb3BfZ3RfNGhycykvIHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHByb3BfZ3RfOGhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9ndF84aHJzKS8gc3VtKHRvdGFsX2F0dGVuZGFuY2UpLA0KICAgICAgICAgICAgcHJvcF9ndF8xMmhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9ndF8xMmhycykvIHN1bSh0b3RhbF9hdHRlbmRhbmNlKSkgDQoNCndhaXRpbmdfdGltZXNfc3VtbWFyeSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdG90YWxfYXR0ZW5kcykpICsNCiAgZ2VvbV9jb2woKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBsYWJzKHkgPSAiQXZlcmFnZSBtb250aGx5IGF0dGVuZGFuY2VzIiwNCiAgICAgICB0aXRsZSA9ICJBdmVyYWdlIEEmRSBhdHRlbmRhbmNlcyIsDQogICAgICAgc3VidGl0bGUgPSAiRnJvbSBKdWx5IDIwMDcgdG8gRGVjZW1iZXIgMjAxOSAiKSArDQogIGdlb21fc21vb3RoKCkNCg0Kd2FpdGluZ190aW1lc19zdW1tYXJ5ICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSBwcm9wX2x0XzRocnMsIGdyb3VwID0gMSkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgbGFicyh0aXRsZSA9ICJTZWFzb25hbGl0eSBvZiBwcm9wb3J0aW9uIG9mIHZpc2l0cyB3aXRoIGEgd2FpdCB0aW1lIDwgNCBob3VycyIsDQogICAgICAgICBzdWJ0aXRsZSA9ICIyMDA3IHRvIDIwMTkiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsNCiAgZ2VvbV9zbW9vdGgoKQ0KDQp3YWl0aW5nX3RpbWVzX3N1bW1hcnkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtb250aCwgeSA9IHByb3BfZ3RfNGhycywgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICAgIGxhYnModGl0bGUgPSAiU2Vhc29uYWxpdHkgb2YgcHJvcG9ydGlvbiBvZiB2aXNpdHMgd2l0aCBhIHdhaXQgdGltZSA+IDQgaG91cnMiLA0KICAgICAgICAgc3VidGl0bGUgPSAiMjAwNyB0byAyMDE5IikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArDQogIGdlb21fc21vb3RoKCkNCg0KDQp3YWl0aW5nX3RpbWVzX3N1bW1hcnkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gcHJvcF9ndF84aHJzLCBncm91cCA9IDEpKSArDQogIGdlb21fcG9pbnQoKSArDQogICAgbGFicyh0aXRsZSA9ICJTZWFzb25hbGl0eSBvZiBwcm9wb3J0aW9uIG9mIHZpc2l0cyB3aXRoIGEgd2FpdCB0aW1lID4gOCBob3VycyIsDQogICAgICAgICBzdWJ0aXRsZSA9ICIyMDA3IHRvIDIwMTkiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsNCiAgZ2VvbV9zbW9vdGgoKQ0KDQoNCndhaXRpbmdfdGltZXNfc3VtbWFyeSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gcHJvcF9ndF8xMmhycywgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgICBsYWJzKHRpdGxlID0gIlNlYXNvbmFsaXR5IG9mIHByb3BvcnRpb24gb2YgdmlzaXRzIHdpdGggYSB3YWl0IHRpbWUgPiAxMiBob3VycyIsDQogICAgICAgICBzdWJ0aXRsZSA9ICJQcmUtY292aWQ6IDIwMDcgdG8gMjAxOSIsDQogICAgICAgICB5ID0gIlBlcmNlbnRhZ2Ugb2YgYXR0ZW5kYW5jZXMgPiAxMiBob3VycyIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSArDQogIGdlb21fc21vb3RoKHNlID0gRkFMU0UpDQoNCg0KDQoNCmBgYA0KVGhlIG51bWJlciBvZiBBJkUgYXR0ZW5kYW5jZXMgZGVjcmVhc2UgZHVyaW5nIHRoZSB3aW50ZXIgbW9udGhzIGhvd2V2ZXIgdGhlIHByb3BvcnRpb24gb2Ygd2FpdCB0aW1lcyBncmVhdGVyIHRoYW4gNGhvdXJzIGluY3JlYXNlcyBzaWduaWZpY2FudGx5IGJldHdlZW4gTm92ZW1iZXIgYW5kIEZlYnJ1YXJ5IGhpZ2hsaWdodGluZyB0aGF0IHRoZSBjb21wbGV4aXR5IG9mIGNhc2VzIGluIHRoZSB3aW50ZXIgbWVhbiB0aGF0IGl0IHRha2VzIGhvc3BpdGFscyBsb25nZXIgdG8gZGlzY2hhcmdlIHBhdGllbnRzLiBQZXJoYXBzIGNvbWJpbmluZyB0aGlzIG91dHB1dCB3aXRoIHRoZSBiZWQgb2NjdXBhdGlvbiByYXRlcyBkdXJpbmcgdGhlIHdpbnRlciBtb250aHMgY291bGQgZnVydGhlciBzdXBwbGVtZW50IHRoaXMgcmVsYXRpb25zaGlwLiANCg0KDQpgYGB7cn0NCg0Kd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgIyBmaWx0ZXIoeWVhciA8PSAyMDE5KSAlPiUgDQogIG11dGF0ZShtb250aCA9IGZhY3Rvcihtb250aCwgbGV2ZWxzID0gYygiSnVseSIsICJBdWd1c3QiLCAiU2VwdGVtYmVyIiwgIk9jdG9iZXIiLCAiTm92ZW1iZXIiLCAiRGVjZW1iZXIiLCAiSmFudWFyeSIsICJGZWJydWFyeSIsICJNYXJjaCIsICJBcHJpbCIsICJNYXkiLCAiSnVuZSIpKSkgJT4lIA0KICBncm91cF9ieShtb250aCwgaGVhbHRoX2JvYXJkKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRzID0gbWVhbih0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHByb3BfbHRfNGhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9sdF80aHJzKS8gc3VtKHRvdGFsX2F0dGVuZGFuY2UpLA0KICAgICAgICAgICAgcHJvcF9ndF80aHJzID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UgKiBwcm9wX2d0XzRocnMpLyBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICBwcm9wX2d0XzhocnMgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSAqIHByb3BfZ3RfOGhycykvIHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHByb3BfZ3RfMTJocnMgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSAqIHByb3BfZ3RfMTJocnMpLyBzdW0odG90YWxfYXR0ZW5kYW5jZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSBwcm9wX2d0XzEyaHJzLCBncm91cCA9IGhlYWx0aF9ib2FyZCwgY29sb3VyID0gaGVhbHRoX2JvYXJkKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGxhYnModGl0bGUgPSAiU2Vhc29uYWxpdHkgb2YgcHJvcG9ydGlvbiBvZiB2aXNpdHMgd2l0aCBhIHdhaXQgdGltZSA+IDEyIGhvdXJzIikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQoNCg0KIyBIb3cgZG8gYXR0ZW5kYW5jZXMgdG8gZGlmZmVyZW50IHNwZWNpYWx0aWVzIGNoYW5nZSBvdmVyIHRpbWU/DQoNCmBgYHtyfQ0KDQpzcGVjaWFsdGllc19yYXcgPC0gcmVhZF9jc3YoaGVyZSgicmF3X2RhdGEvbm9uX2NvdmlkL2lucGF0aWVudF9hbmRfZGF5Y2FzZV9ieV9uaHNfYm9hcmRfb2ZfdHJlYXRtZW50X2FuZF9zcGVjaWFsdHkuY3N2IikpICU+JQ0KICBjbGVhbl9uYW1lcygpDQoNCnNwZWNpYWx0aWVzX3Jhdw0KDQpgYGANCg0KYGBge3J9DQoNCnNwZWNpYWx0aWVzIDwtIHNwZWNpYWx0aWVzX3JhdyAlPiUgDQogIGlubmVyX2pvaW4oaGIsICJoYiIpICU+JSANCiAgaW5uZXJfam9pbihob3NwaXRhbHMsICJsb2NhdGlvbiIpICU+JSANCiAgc2VsZWN0KC1lbmRzX3dpdGgoInFmIiksIC1oYiwgLSBzcGVjaWFsdHkpICU+JSANCiAgc2VsZWN0KHF1YXJ0ZXIsIGhiX25hbWUsIGxvY2F0aW9uLCBsb2NhdGlvbl9uYW1lLCBldmVyeXRoaW5nKCkpICU+JSANCiAgbXV0YXRlKHllYXIgPSBhcy5udW1lcmljKHN0cl9zdWIocXVhcnRlciwxLCA0KSksIC5iZWZvcmUgPSBxdWFydGVyKSAlPiUgDQogIG11dGF0ZShpc19jb3ZpZF95ZWFyID0gY2FzZV93aGVuKA0KICAgIHllYXIgPj0gMjAyMCB+IFRSVUUsDQogICAgeWVhciA8IDIwMjAgfiBGQUxTRQ0KICApKQ0KICAjIG11dGF0ZShxdWFydGVyID0gc3RyX3N1YihxdWFydGVyLCAtMiwgLTEpKQ0KDQpzcGVjaWFsdGllcw0KDQpgYGANCg0KIyBhbGwgZXBpc29kZXMgdnMgdGltZQ0KYGBge3J9DQoNCnNwZWNpYWx0aWVzICU+JSANCiAgZGlzdGluY3QoYWRtaXNzaW9uX3R5cGUpDQoNCnNwZWNpYWx0aWVzICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlcikgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCBJbnBhdGllbnRzIGFuZCBEYXkgY2FzZXMiKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9lcGlzb2RlcyA9IHN1bShlcGlzb2RlcykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHRvdGFsX2VwaXNvZGVzLCBncm91cCA9IDEpKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6Y29tbWEsIGV4cGFuZCA9IGMoMCwwKSwgbGltaXRzID0gYygwLE5BKSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArDQogIGxhYnModGl0bGUgPSAiVG90YWwgYWRtaXNzaW9ucyBmb3IgQWxsIElucGF0aWVudHMgYW5kIERheSBDYXNlcyIsDQogICAgICAgeCA9ICJRdWFydGVyIiwNCiAgICAgICB5ID0gIlRvdGFsIEVwaXNvZGVzIikNCg0KYGBgDQoNCiMgQWxsIERheSBDYXNlcw0KDQpgYGB7cn0NCg0Kc3BlY2lhbHRpZXMgJT4lIA0KICBkaXN0aW5jdChhZG1pc3Npb25fdHlwZSkNCg0Kc3BlY2lhbHRpZXMgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZG1pc3Npb25fdHlwZSkgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgJWluJSBjKCJBbGwgRGF5IGNhc2VzIiwgIkFsbCBJbnBhdGllbnRzIikpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2VwaXNvZGVzID0gc3VtKGVwaXNvZGVzKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gdG90YWxfZXBpc29kZXMsIGNvbG91ciA9IGFkbWlzc2lvbl90eXBlKSkgKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gYWRtaXNzaW9uX3R5cGUpKSArDQogIGdlb21fcG9pbnQoKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmNvbW1hLCBleHBhbmQgPSBjKDAsMCksIGxpbWl0cyA9IGMoMCxOQSkpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKw0KICBsYWJzKHRpdGxlID0gIlRvdGFsIGFkbWlzc2lvbnMgZm9yIEFsbCBEYXkgQ2FzZXMgYW5kIEFsbCBJbnBhdGllbnRzIiwNCiAgICAgICB4ID0gIlF1YXJ0ZXIiLA0KICAgICAgIHkgPSAiVG90YWwgRXBpc29kZXMiLA0KICAgICAgIGNvbCA9ICJBZG1pc3Npb24gVHlwZSIpDQoNCg0KYGBgDQoNCmBgYHtyfQ0KDQphbGxfaW5wYXRpZW50X2NhdHMgPC0gYygiRWxlY3RpdmUgSW5wYXRpZW50cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICJFbWVyZ2VuY3kgSW5wYXRpZW50cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICJUcmFuc2ZlcnMiKQ0KDQpzcGVjaWFsdGllcyAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFkbWlzc2lvbl90eXBlKSAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSAlaW4lIGFsbF9pbnBhdGllbnRfY2F0cykgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfZXBpc29kZXMgPSBzdW0oZXBpc29kZXMpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSB0b3RhbF9lcGlzb2RlcywgY29sb3VyID0gYWRtaXNzaW9uX3R5cGUpKSArDQogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBhZG1pc3Npb25fdHlwZSkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6Y29tbWEsIGV4cGFuZCA9IGMoMCwwKSwgbGltaXRzID0gYygwLE5BKSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArDQogIGxhYnModGl0bGUgPSAiVG90YWwgYWRtaXNzaW9ucyBmb3IgSW5wYXRpZW50cyIsDQogICAgICAgeCA9ICJRdWFydGVyIiwNCiAgICAgICB5ID0gIlRvdGFsIEVwaXNvZGVzIiwNCiAgICAgICBjb2wgPSAiQWRtaXNzaW9uIFR5cGUiKQ0KDQpgYGANCg0KYGBge3J9DQoNCnNwZWNpYWx0aWVzICU+JSANCiAgZGlzdGluY3QoYWRtaXNzaW9uX3R5cGUsIHNwZWNpYWx0eV9uYW1lKQ0KDQpgYGANCg0KYGBge3J9DQoNCnNwZWNpYWx0aWVzICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWRtaXNzaW9uX3R5cGUsIHNwZWNpYWx0eV9uYW1lKSAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IElucGF0aWVudHMiKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9lcGlzb2RlcyA9IHN1bShlcGlzb2RlcykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHRvdGFsX2VwaXNvZGVzLCBjb2xvdXIgPSBzcGVjaWFsdHlfbmFtZSkpICsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNwZWNpYWx0eV9uYW1lKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpjb21tYSwgZXhwYW5kID0gYygwLDApLCBsaW1pdHMgPSBjKDAsMTAwMDApKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsNCiAgbGFicyh0aXRsZSA9ICJUb3RhbCBhZG1pc3Npb25zIGZvciBFbWVyZ2VuY3kgSW5wYXRpZW50cyIsDQogICAgICAgc3VidGl0bGUgPSAiU3BsaXQgYnkgc3BlY2lhbHR5IiwNCiAgICAgICB4ID0gIlF1YXJ0ZXIiLA0KICAgICAgIHkgPSAiVG90YWwgRXBpc29kZXMiLA0KICAgICAgIGNvbCA9ICJBZG1pc3Npb24gVHlwZSIpDQoNCmBgYA0KDQojIFdoaWNoIGRlcGFydG1lbnRzIGNoYW5nZWQgdGhlIG1vc3QgYmV0d2VlbiBDb3ZpZCBhbmQgcHJlLWNvdmlkDQpgYGB7cn0NCg0KdG90YWxfYWRtaXNzaW9ucyA8LSBzcGVjaWFsdGllcyAlPiUgDQogIGdyb3VwX2J5KGlzX2NvdmlkX3llYXIpICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwgSW5wYXRpZW50cyBhbmQgRGF5IGNhc2VzIikgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYWRtaXNzaW9ucyA9IHN1bShlcGlzb2RlcykpICU+JSANCiAgcHVsbCh0b3RhbF9hZG1pc3Npb25zKQ0KDQpjaGFuZ2VfaW5fYXRfc3BlY2lhbHRpZXMgPC0gc3BlY2lhbHRpZXMgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgJWluJSBjKGFsbF9pbnBhdGllbnRfY2F0cywgIkFsbCBEYXkgY2FzZXMiKSkgJT4lIA0KICBncm91cF9ieShhZG1pc3Npb25fdHlwZSwgc3BlY2lhbHR5X25hbWUsIGlzX2NvdmlkX3llYXIpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2VwaXNvZGVzID0gc3VtKGVwaXNvZGVzKSkgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gaXNfY292aWRfeWVhciwgdmFsdWVzX2Zyb20gPSB0b3RhbF9lcGlzb2RlcykgJT4lIA0KICByZW5hbWUoImNvdmlkX3llYXIiID0gIlRSVUUiLCAicHJlX2NvdmlkX3llYXIiID0gIkZBTFNFIikgJT4lIA0KICBtdXRhdGUocHJlX2NvdmlkX3llYXJfcHJvcCA9IHByZV9jb3ZpZF95ZWFyIC8gdG90YWxfYWRtaXNzaW9uc1sxXSwNCiAgICAgICAgIGNvdmlkX3llYXJfcHJvcCA9IGNvdmlkX3llYXIgLyB0b3RhbF9hZG1pc3Npb25zWzJdLA0KICAgICAgICAgcGVyY2VudGFnZV9jaGFuZ2UgPSAoKGNvdmlkX3llYXJfcHJvcCAvIHByZV9jb3ZpZF95ZWFyX3Byb3ApIC0gMSkgKiAxMDApICU+JSANCiAgdW5ncm91cCgpDQoNCg0KYGBgDQoNCg0KDQpgYGB7cn0NCg0Kc3BlY2lhbHRpZXMgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCBEYXkgY2FzZXMiICYgc3BlY2lhbHR5X25hbWUgPT0gIkNhcmRpb3Rob3JhY2ljIFN1cmdlcnkiKSAlPiUgDQogIGdyb3VwX2J5KGlzX2NvdmlkX3llYXIpICU+JSANCiAgc3VtbWFyaXNlKGNvdW50ID0gc3VtKGVwaXNvZGVzKSkNCg0KYGBgDQoNCmBgYHtyfQ0KIyB0b3AgNSBjaGFuZ2VzIGluIHNwZWNpYWx0eSBwcm9wb3J0aW9uDQpjaGFuZ2VfaW5fYXRfc3BlY2lhbHRpZXMgJT4lIA0KICBzbGljZV9tYXgocGVyY2VudGFnZV9jaGFuZ2UsIG4gPSA1KQ0KDQojIHNvcnQgYnkgbGFyZ2VzdCBwcm9wb3J0aW9uLCB0b3AgNQ0KY2hhbmdlX2luX2F0X3NwZWNpYWx0aWVzICU+JSANCiAgc2xpY2VfbWF4KHBlcmNlbnRhZ2VfY2hhbmdlLCBuID0gNSkgJT4lIA0KICBhcnJhbmdlKGRlc2MoY292aWRfeWVhcl9wcm9wKSkNCg0KYGBgDQoNCmBgYHtyfQ0KDQpjaGFuZ2VfaW5fYXRfc3BlY2lhbHRpZXMgJT4lIA0KICBmaWx0ZXIoY292aWRfeWVhciA+IDEwMDApICU+JSANCiAgc2xpY2VfbWF4KHBlcmNlbnRhZ2VfY2hhbmdlLCBuID0gNSkgJT4lIA0KICBtdXRhdGUobGFiZWwgPSBzdHJfYyhzcGVjaWFsdHlfbmFtZSwgIlxuKCIsIGFkbWlzc2lvbl90eXBlLCAiKSIpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHJlb3JkZXIobGFiZWwsIHNvcnQocGVyY2VudGFnZV9jaGFuZ2UpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gcGVyY2VudGFnZV9jaGFuZ2UpKSArDQogIGdlb21fY29sKCkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLDApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKSArDQogIGxhYnMoeSA9ICJQZXJjZW50YWdlIEluY3JlYXNlICglKSIsDQogICAgICAgdGl0bGUgPSAiVG9wIDUgaW5jcmVhc2VzIGluIGhvc3BpdGFsIGFkbWlzc2lvbnMgKGJ5IHNwZWNpYWx0eSBhbmQgYWRtaXNzaW9uIHR5cGUpIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJNb3JlIHRoYW4gMSwwMDAgYWRtaXNzaW9ucyIpDQoNCmBgYA0KDQpgYGB7cn0NCg0KY2hhbmdlX2luX3NwZWNpYWx0aWVzIDwtIHNwZWNpYWx0aWVzICU+JSANCiAgZ3JvdXBfYnkoc3BlY2lhbHR5X25hbWUsIGlzX2NvdmlkX3llYXIpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2VwaXNvZGVzID0gc3VtKGVwaXNvZGVzKSkgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gaXNfY292aWRfeWVhciwgdmFsdWVzX2Zyb20gPSB0b3RhbF9lcGlzb2RlcykgJT4lIA0KICByZW5hbWUoImNvdmlkX3llYXIiID0gIlRSVUUiLCAicHJlX2NvdmlkX3llYXIiID0gIkZBTFNFIikgJT4lIA0KICBtdXRhdGUocHJlX2NvdmlkX3llYXJfcHJvcCA9IHByZV9jb3ZpZF95ZWFyIC8gdG90YWxfYWRtaXNzaW9uc1sxXSwNCiAgICAgICAgIGNvdmlkX3llYXJfcHJvcCA9IGNvdmlkX3llYXIgLyB0b3RhbF9hZG1pc3Npb25zWzJdLA0KICAgICAgICAgcGVyY2VudGFnZV9jaGFuZ2UgPSAoKGNvdmlkX3llYXJfcHJvcCAvIHByZV9jb3ZpZF95ZWFyX3Byb3ApIC0gMSkgKiAxMDApICU+JSANCiAgdW5ncm91cCgpDQoNCmNoYW5nZV9pbl9zcGVjaWFsdGllcyAlPiUgDQogIHNsaWNlX21heChwZXJjZW50YWdlX2NoYW5nZSwgbiA9IDUpICU+JSANCiAgZmlsdGVyKHBlcmNlbnRhZ2VfY2hhbmdlID4gMCkgJT4lIA0KICBhcnJhbmdlKGRlc2MocGVyY2VudGFnZV9jaGFuZ2UpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHJlb3JkZXIoc3BlY2lhbHR5X25hbWUsIHBlcmNlbnRhZ2VfY2hhbmdlLCBkZWNyZWFzaW5nID0gVFJVRSksDQogICAgICAgICAgICAgeSA9IHBlcmNlbnRhZ2VfY2hhbmdlKSkgKw0KICBnZW9tX2NvbCgpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgKw0KICBsYWJzKHkgPSAiUGVyY2VudGFnZSBJbmNyZWFzZSAoJSkiLA0KICAgICAgIHRpdGxlID0gIlRvcCA1IGNoYW5nZXMgaW4gaG9zcGl0YWwgYWRtaXNzaW9ucyAoYnkgc3BlY2lhbHR5KSAtIHByZS1Db3ZpZCB2cyBDb3ZpZCIsDQogICAgICAgc3VidGl0bGUgPSAiTW9yZSB0aGFuIDEsMDAwIGFkbWlzc2lvbnMiKQ0KDQpgYGANCg0KYGBge3J9DQoNCg0Kd3Rfd2l0aF9kaXNjaGFyZ2VzIDwtIHdhaXRpbmdfdGltZXNfcmF3ICU+JSANCiAgbXV0YXRlKGRhdGVfeW0gPSB5bShtb250aCksIC5iZWZvcmUgPSBtb250aCwNCiAgICAgICAgIG1vbnRoID0gbW9udGgoZGF0ZV95bSwgbGFiZWwgPSBUUlVFLCBhYmJyID0gRkFMU0UpLA0KICAgICAgICAgeWVhciA9IHllYXIoZGF0ZV95bSkpICU+JSANCiAgbGVmdF9qb2luKGhiLCBjKCJoYnQiID0gImhiIikpICU+JSANCiAgbGVmdF9qb2luKGhvc3BpdGFscywgYygidHJlYXRtZW50X2xvY2F0aW9uIiA9ICJsb2NhdGlvbiIpKSAlPiUgDQogIHJlbmFtZSh0b3RhbF9hdHRlbmRhbmNlID0gbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSwNCiAgICAgICAgIHdhaXRfbHRfNGhycyA9IG51bWJlcl9tZWV0aW5nX3RhcmdldF9hZ2dyZWdhdGUsDQogICAgICAgICB3YWl0X2d0XzhocnMgPSBhdHRlbmRhbmNlX2dyZWF0ZXI4aHJzLA0KICAgICAgICAgd2FpdF9ndF8xMmhycyA9IGF0dGVuZGFuY2VfZ3JlYXRlcjEyaHJzLA0KICAgICAgICAgaGVhbHRoX2JvYXJkID0gaGJfbmFtZSwNCiAgICAgICAgIGhvc3BpdGFsX2lkID0gdHJlYXRtZW50X2xvY2F0aW9uLCANCiAgICAgICAgIGhvc3BpdGFsX25hbWUgPSBsb2NhdGlvbl9uYW1lKSAlPiUgDQogIHNlbGVjdCgtZW5kc193aXRoKCJxZiIpKSAlPiUgDQogIHNlbGVjdChkYXRlX3ltLCB5ZWFyLCBtb250aCwgaGVhbHRoX2JvYXJkLCBob3NwaXRhbF9pZCwgaG9zcGl0YWxfbmFtZSwNCiAgICAgICAgIGV2ZXJ5dGhpbmcoKSwgLWNvdW50cnksIC0gaGJ0KQ0KDQojIGNoZWNrIGlmIHRoZXJlIGlzIGEgdHJlbmQgYWNyb3NzIGFsbCB5ZWFycw0Kd3Rfd2l0aF9kaXNjaGFyZ2VzICU+JSANCiAgZ3JvdXBfYnkoZGF0ZV95bSwgaG9zcGl0YWxfbmFtZSkgJT4lIA0KICBzdW1tYXJpc2UodHJhbnNmZXJzID0gc3VtKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl90cmFuc2ZlciwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkYXRlX3ltLCB5ID0gdHJhbnNmZXJzLCBjb2wgPSBob3NwaXRhbF9uYW1lKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KIyBjaGVjayBpZiB0aGVyZSBpcyBhIHNlYXNvbmFsIHRyZW5kDQp3dF93aXRoX2Rpc2NoYXJnZXMgJT4lIA0KICBtdXRhdGUobW9udGggPSBmYWN0b3IobW9udGgsIGxldmVscyA9IGMoIkp1bHkiLCAiQXVndXN0IiwgIlNlcHRlbWJlciIsICJPY3RvYmVyIiwgIk5vdmVtYmVyIiwgIkRlY2VtYmVyIiwgIkphbnVhcnkiLCAiRmVicnVhcnkiLCAiTWFyY2giLCAiQXByaWwiLCAiTWF5IiwgIkp1bmUiKSkpICU+JSANCiAgZ3JvdXBfYnkobW9udGgsIGhlYWx0aF9ib2FyZCkgJT4lIA0KICBzdW1tYXJpc2UodHJhbnNmZXJzID0gc3VtKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl9vdGhlcl9zcGVjaWFsdHksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB0cmFuc2ZlcnMsIGdyb3VwID0gaGVhbHRoX2JvYXJkLCBjb2wgPSBoZWFsdGhfYm9hcmQpKSArDQogIGdlb21fbGluZSgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGZhY2V0X3dyYXAofiBoZWFsdGhfYm9hcmQsIHNjYWxlcyA9ICJmcmVlX3kiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpDQoNCmBgYA0KDQojIEJlZCBvY2N1cGFuY3kgZGF0YQ0KDQpgYGB7cn0NCg0KYmVkc19yYXcgPC0gcmVhZF9jc3YoaGVyZSgicmF3X2RhdGEvbm9uX2NvdmlkL2JlZHNfYnlfbmhzX2JvYXJkX29mX3RyZWF0bWVudF9hbmRfc3BlY2lhbHR5LmNzdiIpKSAlPiUgDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICBzZWxlY3QoLWVuZHNfd2l0aCgicWYiKSkgDQoNCmBgYA0KDQpgYGB7cn0NCiMgYWxsIHNwZWNpYWx0eSBuYW1lcw0KYmVkc19yYXcgJT4lIA0KICBncm91cF9ieShzcGVjaWFsdHlfbmFtZSkgJT4lIA0KICBzdW1tYXJpc2Uoc3VtKGFsbF9zdGFmZmVkX2JlZGRheXMpKQ0KDQpiZWRzX3JhdyAlPiUgDQogIGZpbHRlcihzcGVjaWFsdHlfbmFtZSAhPSAiQWxsIEFjdXRlIiAmIHNwZWNpYWx0eV9uYW1lICE9ICJBbGwgU3BlY2lhbHRpZXMiKSAlPiUgDQogICMgZ3JvdXBfYnkoc3BlY2lhbHR5X25hbWUpICU+JSANCiAgc3VtbWFyaXNlKHN1bShhbGxfc3RhZmZlZF9iZWRkYXlzKSkNCiMgMjA5MTM5NjYwDQoNCg0KYmVkcyA8LSBiZWRzX3JhdyAlPiUgDQogIGxlZnRfam9pbihoYiwgImhiIikgJT4lIA0KICBsZWZ0X2pvaW4oaG9zcGl0YWxzLCAibG9jYXRpb24iKSAlPiUgDQogIHNlbGVjdChxdWFydGVyLCBoYiwgaGJfbmFtZSwgbG9jYXRpb24sIGxvY2F0aW9uX25hbWUsIHNwZWNpYWx0eV9uYW1lOnBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSAlPiUgDQogIG11dGF0ZSgpDQoNCg0KDQpgYGANCg0KYGBge3J9DQoNCmJlZHMgJT4lIA0KICBncm91cF9ieShxdWFydGVyKSAlPiUgDQogIHN1bW1hcmlzZShzdGFmZmVkX2JlZHMgPSBzdW0oYWxsX3N0YWZmZWRfYmVkZGF5cyksDQogICAgICAgICAgICBvY2N1cGllZF9iZWRzID0gc3VtKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpLCANCiAgICAgICAgICAgIG9jY3VwYXRpb25fcGVyY2VudGFnZSA9IG9jY3VwaWVkX2JlZHMgLyBzdGFmZmVkX2JlZHMgKiAxMDApICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IG9jY3VwYXRpb25fcGVyY2VudGFnZSwgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX2xpbmUoKQ0KDQpgYGANCg0KIyBXYWl0IHRpbWVzIC0gYmFzZWxpbmUgKHByZS1jb3ZpZCB2cyBjb3ZpZCkNCg0KIyMgUGVyY2VudGFnZSBvZiB3YWl0IHRpbWVzIHdpdGhpbiB0YXJnZXQgKDw0aHJzKSANCg0KYGBge3J9DQoNCiMgcHJlLWNvdmlkIDw9IDIwMTksIGNvdmlkID0+IDIwMjANCg0KYXZnX3d0X3RhcmdldF9wcmVfY292aWQgPC0gd2FpdGluZ190aW1lcyAlPiUgDQogIGZpbHRlcih5ZWFyIDw9IDIwMTkpICU+JSANCiAgZ3JvdXBfYnkobW9udGgpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICB0b3RhbF93YWl0X2x0XzRocnMgPSBzdW0od2FpdF9sdF80aHJzKSwNCiAgICAgICAgICAgIHRhcmdldF93YWl0X3Byb3AgPSB0b3RhbF93YWl0X2x0XzRocnMgLyB0b3RhbF9hdHRlbmRhbmNlKQ0KDQphdmdfd3RfdGFyZ2V0X3ByZV9jb3ZpZCAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdGFyZ2V0X3dhaXRfcHJvcCwgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGdlb21fc21vb3RoKHNlID0gMCkNCg0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGZpbHRlcih5ZWFyID49IDIwMjApICU+JQ0KICBncm91cF9ieSh5ZWFyLCBtb250aCkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHRvdGFsX3dhaXRfbHRfNGhycyA9IHN1bSh3YWl0X2x0XzRocnMpLA0KICAgICAgICAgICAgdGFyZ2V0X3dhaXRfcHJvcCA9IHRvdGFsX3dhaXRfbHRfNGhycyAvIHRvdGFsX2F0dGVuZGFuY2UpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB0YXJnZXRfd2FpdF9wcm9wLA0KICAgICAgICAgICAgICAgIGdyb3VwID0gZmFjdG9yKHllYXIpLCBjb2wgPSBmYWN0b3IoeWVhcikpKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBhdmdfd3RfdGFyZ2V0X3ByZV9jb3ZpZCwgYWVzKHggPSBtb250aCwgeSA9IHRhcmdldF93YWl0X3Byb3AsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cCA9IDEsIGNvbG91ciA9ICJCYXNlbGluZSIpLA0KICAgICAgICAgICAgICBzaXplID0gMSkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBhdmdfd3RfdGFyZ2V0X3ByZV9jb3ZpZCwgYWVzKHggPSBtb250aCwgeSA9IHRhcmdldF93YWl0X3Byb3AsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cCA9IDEsIGNvbG91ciA9ICJCYXNlbGluZSIpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbChuYW1lID0gIlllYXIiLCB2YWx1ZXMgPSBjKCJCYXNlbGluZSIgPSAiZGFya2JsdWUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjAyMCIgPSAicmVkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMjEiID0gImdyZWVuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMjIiID0gIm9yYW5nZSIpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgbGFicyh5ID0gIlBlcmNlbnRhZ2Ugb2YgYWRtaXNzaW9ucyAoJSkiLA0KICAgICAgIHRpdGxlID0gIlByb3BvcnRpb24gb2Ygd2FpdGluZyB0aW1lcyBncmVhdGVyIHRoYW4gMTIgaG91cnMiLA0KICAgICAgIHN1YnRpdGxlID0gIlByZS1jb3ZpZCAoMjAwNy0yMDE5KSB2cyBjb3ZpZCAoMjAyMCspIiwNCiAgICAgICBjb2wgPSAiWWVhciIpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQoNCmBgYA0KDQojIyBQZXJjZW50YWdlIG9mIHdhaXQgdGltZXMgPjhocnMgDQoNCmBgYHtyfQ0KDQphdmdfd3RfZ3RfOGhyc19wcmVfY292aWQgPC0gd2FpdGluZ190aW1lcyAlPiUgDQogIGZpbHRlcih5ZWFyIDw9IDIwMTkpICU+JSANCiAgZ3JvdXBfYnkobW9udGgpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICB0b3RhbF93YWl0X2d0XzhocnMgPSBzdW0od2FpdF9ndF84aHJzKSwNCiAgICAgICAgICAgIHRhcmdldF93YWl0X3Byb3AgPSB0b3RhbF93YWl0X2d0XzhocnMgLyB0b3RhbF9hdHRlbmRhbmNlKQ0KDQphdmdfd3RfZ3RfOGhyc19wcmVfY292aWQgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtb250aCwgeSA9IHRhcmdldF93YWl0X3Byb3AsIGdyb3VwID0gMSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBnZW9tX3Ntb290aChzZSA9IDApDQoNCndhaXRpbmdfdGltZXMgJT4lIA0KICBmaWx0ZXIoeWVhciA+PSAyMDIwKSAlPiUNCiAgZ3JvdXBfYnkoeWVhciwgbW9udGgpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICB0b3RhbF93YWl0X2d0XzhocnMgPSBzdW0od2FpdF9ndF84aHJzKSwNCiAgICAgICAgICAgIHRhcmdldF93YWl0X3Byb3AgPSB0b3RhbF93YWl0X2d0XzhocnMgLyB0b3RhbF9hdHRlbmRhbmNlKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdGFyZ2V0X3dhaXRfcHJvcCwNCiAgICAgICAgICAgICAgICBncm91cCA9IGZhY3Rvcih5ZWFyKSwgY29sID0gZmFjdG9yKHllYXIpKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fbGluZShkYXRhID0gYXZnX3d0X2d0XzhocnNfcHJlX2NvdmlkLCBhZXMoeCA9IG1vbnRoLCB5ID0gdGFyZ2V0X3dhaXRfcHJvcCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gMSwgY29sb3VyID0gIkJhc2VsaW5lIiksDQogICAgICAgICAgICAgIHNpemUgPSAxKSArDQogICAgZ2VvbV9wb2ludChkYXRhID0gYXZnX3d0X2d0XzhocnNfcHJlX2NvdmlkLCBhZXMoeCA9IG1vbnRoLCB5ID0gdGFyZ2V0X3dhaXRfcHJvcCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gMSwgY29sb3VyID0gIkJhc2VsaW5lIikpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiWWVhciIsIHZhbHVlcyA9IGMoIkJhc2VsaW5lIiA9ICJkYXJrYmx1ZSIsICIyMDIwIiA9ICJyZWQiLCAiMjAyMSIgPSAiZ3JlZW4iLCAiMjAyMiIgPSAib3JhbmdlIikpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKw0KICBsYWJzKHkgPSAiUGVyY2VudGFnZSBvZiBhZG1pc3Npb25zICglKSIsDQogICAgICAgdGl0bGUgPSAiUHJvcG9ydGlvbiBvZiB3YWl0aW5nIHRpbWVzIGdyZWF0ZXIgdGhhbiA4IGhvdXJzIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJQcmUtY292aWQgKDIwMDctMjAxOSkgdnMgY292aWQgKDIwMjArKSIsDQogICAgICAgY29sID0gIlllYXIiKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KYGBgDQoNCiMjIFBlcmNlbnRhZ2Ugb2Ygd2FpdCB0aW1lcyA+MTJocnMgDQoNCmBgYHtyfQ0KDQphdmdfd3RfZ3RfMTJocnNfcHJlX2NvdmlkIDwtIHdhaXRpbmdfdGltZXMgJT4lIA0KICBmaWx0ZXIoeWVhciA8PSAyMDE5KSAlPiUgDQogIGdyb3VwX2J5KG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpLA0KICAgICAgICAgICAgdG90YWxfd2FpdF9ndF8xMmhycyA9IHN1bSh3YWl0X2d0XzEyaHJzKSwNCiAgICAgICAgICAgIHRhcmdldF93YWl0X3Byb3AgPSB0b3RhbF93YWl0X2d0XzEyaHJzIC8gdG90YWxfYXR0ZW5kYW5jZSkNCg0KYXZnX3d0X2d0XzEyaHJzX3ByZV9jb3ZpZCAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdGFyZ2V0X3dhaXRfcHJvcCwgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGdlb21fc21vb3RoKHNlID0gMCkNCg0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGZpbHRlcih5ZWFyID49IDIwMjApICU+JQ0KICBncm91cF9ieSh5ZWFyLCBtb250aCkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHRvdGFsX3dhaXRfZ3RfMTJocnMgPSBzdW0od2FpdF9ndF8xMmhycyksDQogICAgICAgICAgICB0YXJnZXRfd2FpdF9wcm9wID0gdG90YWxfd2FpdF9ndF8xMmhycyAvIHRvdGFsX2F0dGVuZGFuY2UpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB0YXJnZXRfd2FpdF9wcm9wLA0KICAgICAgICAgICAgICAgIGdyb3VwID0gZmFjdG9yKHllYXIpLCBjb2wgPSBmYWN0b3IoeWVhcikpKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBhdmdfd3RfZ3RfMTJocnNfcHJlX2NvdmlkLCBhZXMoeCA9IG1vbnRoLCB5ID0gdGFyZ2V0X3dhaXRfcHJvcCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gMSwgY29sb3VyID0gIkJhc2VsaW5lIiksDQogICAgICAgICAgICAgIHNpemUgPSAxKSArDQogICAgZ2VvbV9wb2ludChkYXRhID0gYXZnX3d0X2d0XzEyaHJzX3ByZV9jb3ZpZCwgYWVzKHggPSBtb250aCwgeSA9IHRhcmdldF93YWl0X3Byb3AsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cCA9IDEsIGNvbG91ciA9ICJCYXNlbGluZSIpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbChuYW1lID0gIlllYXIiLCB2YWx1ZXMgPSBjKCJCYXNlbGluZSIgPSAiZGFya2JsdWUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjAyMCIgPSAicmVkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMjEiID0gImdyZWVuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMjIiID0gIm9yYW5nZSIpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgbGFicyh5ID0gIlBlcmNlbnRhZ2Ugb2YgYWRtaXNzaW9ucyAoJSkiLA0KICAgICAgIHRpdGxlID0gIlByb3BvcnRpb24gb2Ygd2FpdGluZyB0aW1lcyBncmVhdGVyIHRoYW4gMTIgaG91cnMiLA0KICAgICAgIHN1YnRpdGxlID0gIlByZS1jb3ZpZCAoMjAwNy0yMDE5KSB2cyBjb3ZpZCAoMjAyMCspIiwNCiAgICAgICBjb2wgPSAiWWVhciIpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQpgYGANCg0KDQojIEphY2sncyBxdWVzdGlvbjoNCg0KYGBge3J9DQoNCmJlZHNfdHJlYXRtZW50X3NwZWNpYWx0eSA8LSBiZWRzDQoNCg0KZGYxIDwtIGJlZHNfdHJlYXRtZW50X3NwZWNpYWx0eSAlPiUgI3ByZSBjb3ZpZCBkYXRlcywgYWxsIGhlYWx0aCBiYW9yZHMNCiAgbXV0YXRlKGRhdGUgPSB5cShxdWFydGVyKSwgbW9udGggPSBtb250aChkYXRlLCBsYWJlbCA9IFRSVUUsIGFiYnIgPSBUUlVFKSwNCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGUpKSAlPiUgDQogIGZpbHRlcih5ZWFyIDw9IDIwMTksIGhiID09ICJTMDgwMDAwMTUiKSAlPiUgIyBoYiBzZWxlY3RlZCBieSB1c2VyIGlucHV0DQogIGdyb3VwX2J5KG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfb2NjdXBhbmN5ID0gbWVhbihwZXJjZW50YWdlX29jY3VwYW5jeSwgbmEucm0gPSBUUlVFKSkNCg0KDQpkZjIgPC0gYmVkc190cmVhdG1lbnRfc3BlY2lhbHR5ICU+JSANCiAgbXV0YXRlKGRhdGUgPSB5cShxdWFydGVyKSwgbW9udGggPSBtb250aChkYXRlLCBsYWJlbCA9IFRSVUUsIGFiYnIgPSBUUlVFKSwNCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGUpKSAlPiUgDQogIGZpbHRlcih5ZWFyID4gMjAxOSwgaGIgPT0gIlMwODAwMDAxNSIpICU+JSAjcG9zdCBjb3ZpZCwgZmlsdGVyIGJhc2VkIG9uIG1hcCBpbnB1dA0KICBncm91cF9ieSh5ZWFyLCBtb250aCkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX29jY3VwYW5jeSA9IG1lYW4ocGVyY2VudGFnZV9vY2N1cGFuY3ksIG5hLnJtID0gVFJVRSkpDQoNCiMjIG5vIGxvbmdlciByZXF1aXJlZA0KIyBkZjMgPC0gZGYxICU+JSANCiMgICBtdXRhdGUoVHlwZSA9ICJiYXNlbGluZSIpICU+JSANCiMgICBiaW5kX3Jvd3MoZGYyICU+JSANCiMgICAgICAgICAgICAgICBtdXRhdGUoVHlwZSA9ICJwb3N0LWNvdmlkIikpDQoNCmRmMiAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gYXZnX29jY3VwYW5jeSwgY29sb3VyID0gZmFjdG9yKHllYXIpLCBncm91cCA9IHllYXIpKSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBkZjEsIGFlcyh4ID0gbW9udGgsIHkgPSBhdmdfb2NjdXBhbmN5LCBncm91cCA9IDEsIGNvbCA9ICJCYXNlbGluZSIpKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IGRmMSwgYWVzKHggPSBtb250aCwgeSA9IGF2Z19vY2N1cGFuY3ksIGdyb3VwID0gMSwgY29sID0gIkJhc2VsaW5lIikpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiWWVhciIsIHZhbHVlcyA9IGMoIkJhc2VsaW5lIiA9ICJkYXJrYmx1ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyMDIwIiA9ICJyZWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjAyMSIgPSAiZ3JlZW4iKSkgKw0KICBsYWJzKHRpdGxlID0gIkF2ZyBPY2N1cGFuY3kgYnkgSGVhbHRoIEJvYXJkIHZzIEJhc2VsaW5lIiwgIyBuZWVkIHRvIHVwZGF0ZSB0aGVzZQ0KICAgICAgIHggPSAiTW9udGgiLA0KICAgICAgIHkgPSAiQXZnIE9jY3VwYW5jeSBSYXRlIikNCg0KDQpkZjJfd2lkZSA8LSBkZjIgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0geWVhciwgdmFsdWVzX2Zyb20gPSBhdmdfb2NjdXBhbmN5KQ0KDQpkZjEyIDwtIGRmMSAlPiUgDQogIHJlbmFtZShiYXNlbGluZSA9IGF2Z19vY2N1cGFuY3kpICU+JSANCiAgbGVmdF9qb2luKGRmMl93aWRlLCAibW9udGgiKQ0KDQpkZjEyDQpgYGANCg0KYGBge3J9DQoNCmRmMyA8LSBiZWRzX3RyZWF0bWVudF9zcGVjaWFsdHkgJT4lICNwcmUgY292aWQgZGF0ZXMsIGFsbCBoZWFsdGggYmFvcmRzDQogIG11dGF0ZShkYXRlID0geXEocXVhcnRlciksIG1vbnRoID0gbW9udGgoZGF0ZSwgbGFiZWwgPSBUUlVFLCBhYmJyID0gVFJVRSksDQogICAgICAgICB5ZWFyID0geWVhcihkYXRlKSkgJT4lIA0KICBmaWx0ZXIoeWVhciA8PSAyMDE5LCBoYiA9PSAiUzA4MDAwMDE1IikgJT4lICMgaGIgc2VsZWN0ZWQgYnkgdXNlciBpbnB1dA0KICBncm91cF9ieShtb250aCkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXZhaWxhYmxlID0gc3VtKGFsbF9zdGFmZmVkX2JlZGRheXMpLCANCiAgICAgICAgICAgIHRvdGFsX29jY3VwaWVkID0gc3VtKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpLA0KICAgICAgICAgICAgYXZnX29jY3VwYW5jeSA9IHRvdGFsX29jY3VwaWVkIC8gdG90YWxfYXZhaWxhYmxlKQ0KDQoNCmRmNCA8LSBiZWRzX3RyZWF0bWVudF9zcGVjaWFsdHkgJT4lIA0KICBtdXRhdGUoZGF0ZSA9IHlxKHF1YXJ0ZXIpLCBtb250aCA9IG1vbnRoKGRhdGUsIGxhYmVsID0gVFJVRSwgYWJiciA9IFRSVUUpLA0KICAgICAgICAgeWVhciA9IHllYXIoZGF0ZSkpICU+JSANCiAgZmlsdGVyKHllYXIgPiAyMDE5LCBoYiA9PSAiUzA4MDAwMDE1IikgJT4lICNwb3N0IGNvdmlkLCBmaWx0ZXIgYmFzZWQgb24gbWFwIGlucHV0DQogIGdyb3VwX2J5KHllYXIsIG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdmFpbGFibGUgPSBzdW0oYWxsX3N0YWZmZWRfYmVkZGF5cyksIA0KICAgICAgICAgICAgdG90YWxfb2NjdXBpZWQgPSBzdW0odG90YWxfb2NjdXBpZWRfYmVkZGF5cyksDQogICAgICAgICAgICBhdmdfb2NjdXBhbmN5ID0gdG90YWxfb2NjdXBpZWQgLyB0b3RhbF9hdmFpbGFibGUpDQoNCmRmNCAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gYXZnX29jY3VwYW5jeSwgY29sb3VyID0gZmFjdG9yKHllYXIpLCBncm91cCA9IHllYXIpKSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBkZjMsIGFlcyh4ID0gbW9udGgsIHkgPSBhdmdfb2NjdXBhbmN5LCBncm91cCA9IDEsIGNvbCA9ICJCYXNlbGluZSIpKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IGRmMywgYWVzKHggPSBtb250aCwgeSA9IGF2Z19vY2N1cGFuY3ksIGdyb3VwID0gMSwgY29sID0gIkJhc2VsaW5lIikpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiWWVhciIsIHZhbHVlcyA9IGMoIkJhc2VsaW5lIiA9ICJkYXJrYmx1ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyMDIwIiA9ICJyZWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjAyMSIgPSAiZ3JlZW4iKSkgKw0KICBsYWJzKHRpdGxlID0gIkF2ZyBPY2N1cGFuY3kgYnkgSGVhbHRoIEJvYXJkIHZzIEJhc2VsaW5lIiwgIyBuZWVkIHRvIHVwZGF0ZSB0aGVzZQ0KICAgICAgIHggPSAiTW9udGgiLA0KICAgICAgIHkgPSAiQXZnIE9jY3VwYW5jeSBSYXRlIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KQ0KDQoNCmRmNF93aWRlIDwtIGRmMiAlPiUgDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSB5ZWFyLCB2YWx1ZXNfZnJvbSA9IGF2Z19vY2N1cGFuY3kpDQoNCmRmMzQgPC0gZGYzICU+JSANCiAgcmVuYW1lKGJhc2VsaW5lID0gYXZnX29jY3VwYW5jeSkgJT4lIA0KICBsZWZ0X2pvaW4oZGYyX3dpZGUsICJtb250aCIpICU+JSANCiAgc2VsZWN0KC10b3RhbF9hdmFpbGFibGUsIC0gdG90YWxfb2NjdXBpZWQpICU+JSANCiAgbXV0YXRlKGJhc2VsaW5lID0gYmFzZWxpbmUgKiAxMDApDQoNCmBgYA0KDQpgYGB7cn0NCiMgd2VpZ2h0ZWQgYXZlcmFnZSBvY2N1cGFuY3kgcmF0ZQ0KZGYzNA0KDQpgYGANCg0KYGBge3J9DQojIGF2ZXJhZ2Ugb2Ygb2NjdXBhbmN5IHBlcmNlbnRhZ2VzDQpkZjEyDQoNCmBgYA0KIyBob3cgZG9lcyBiZWQgdXNhZ2UgY2hhbmdlIG92ZXIgdGltZQ0KYGBge3J9DQoNCmJlZHMgJT4lDQogIGdyb3VwX2J5KHF1YXJ0ZXIpICU+JQ0KICBzdW1tYXJpc2UoYmVkc19hdmFpbGFibGUgPSBzdW0oYWxsX3N0YWZmZWRfYmVkZGF5cyksDQogICAgICAgICAgICBiZWRzX29jY3VwaWVkID0gc3VtKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGJlZHNfYXZhaWxhYmxlOmJlZHNfb2NjdXBpZWQsIG5hbWVzX3RvID0gImJlZF90eXBlIiwNCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJudW1fYmVkcyIpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IG51bV9iZWRzLCBjb2xvdXIgPSBiZWRfdHlwZSwgZ3JvdXAgPSBiZWRfdHlwZSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpjb21tYSkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSArDQogIGxhYnMoeSA9ICJOdW1iZXIgb2YgYmVkIGRheXMiLA0KICAgICAgIHRpdGxlID0gIk51bWJlciBvZiBiZWRzIGF2YWlsYWJsZS9vY2N1cGllZCBvdmVyIHRpbWUiLA0KICAgICAgIGNvbCA9ICJCZWQgVHlwZSIpDQoNCmBgYA0KIyBiZWQgdXNlIGJ5IHNwZWNpYWx0eQ0KYGBge3J9DQoNCmJlZHMgJT4lDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIHNwZWNpYWx0eV9uYW1lKSAlPiUNCiAgIyBmaWx0ZXIoc3BlY2lhbHR5X25hbWUgJWluJSBjKCJDbGluaWNhbCBSYWRpb2xvZ3kiLCAiSW50ZW5zaXZlIENhcmUgTWVkaWNpbmUiKSkgJT4lIA0KICBzdW1tYXJpc2UoYmVkc19hdmFpbGFibGUgPSBzdW0oYWxsX3N0YWZmZWRfYmVkZGF5cyksDQogICAgICAgICAgICBiZWRzX29jY3VwaWVkID0gc3VtKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGJlZHNfYXZhaWxhYmxlOmJlZHNfb2NjdXBpZWQsIG5hbWVzX3RvID0gImJlZF90eXBlIiwNCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJudW1fYmVkcyIpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IG51bV9iZWRzLCBjb2xvdXIgPSBzcGVjaWFsdHlfbmFtZSwgZ3JvdXAgPSBzcGVjaWFsdHlfbmFtZSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBmYWNldF93cmFwKH5iZWRfdHlwZSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpjb21tYSkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSArDQogIGxhYnMoeSA9ICJOdW1iZXIgb2YgYmVkIGRheXMiLA0KICAgICAgIHRpdGxlID0gIk51bWJlciBvZiBiZWRzIGF2YWlsYWJsZS9vY2N1cGllZCBvdmVyIHRpbWUiLA0KICAgICAgIGNvbCA9ICJCZWQgVHlwZSIpDQoNCmBgYA0KDQpgYGB7cn0NCg0KYmVkcyAlPiUgDQogIG11dGF0ZSh5ZWFyID0gYXMubnVtZXJpYyhzdHJfZXh0cmFjdChxdWFydGVyLCAiWzAtOV17NH0iKSksDQogICAgaXNfY292aWRfeWVhciA9IGNhc2Vfd2hlbigNCiAgICB5ZWFyIDw9IDIwMTkgfiBGQUxTRSwNCiAgICB5ZWFyID49IDIwMjAgfiBUUlVFDQogICAgKSkgJT4lIA0KICBncm91cF9ieShzcGVjaWFsdHlfbmFtZSwgaXNfY292aWRfeWVhcikgJT4lIA0KICBzdW1tYXJpc2UoYmVkc19hdmFpbGFibGUgPSBzdW0oYWxsX3N0YWZmZWRfYmVkZGF5cyksDQogICAgICAgICAgICBiZWRzX29jY3VwaWVkID0gc3VtKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpKSAlPiUgDQogIHNlbGVjdChzcGVjaWFsdHlfbmFtZSwgaXNfY292aWRfeWVhciwgYmVkc19vY2N1cGllZCkgJT4lICANCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGlzX2NvdmlkX3llYXIsIHZhbHVlc19mcm9tID0gYmVkc19vY2N1cGllZCkgJT4lIA0KICByZW5hbWUoInByZV9jb3ZpZCIgPSAiRkFMU0UiLCAiY292aWQiID0gIlRSVUUiKSAlPiUgDQogIGRyb3BfbmEoKSAlPiUgDQogIG11dGF0ZShkaWZmX29jY3VwaWVkID0gY292aWQgLSBwcmVfY292aWQsDQogICAgICAgICBkaWZmX29jY3VwaWVkX3BjID0gKChjb3ZpZCAvIHByZV9jb3ZpZCkgLSAxKSAqIDEwMCkgJT4lIA0KICBmaWx0ZXIoZGlmZl9vY2N1cGllZF9wYyA+IDApICU+JSANCiAgYXJyYW5nZShkZXNjKGRpZmZfb2NjdXBpZWRfcGMpKQ0KICANCg0KYGBgDQojIHdhaXRpbmcgdGltZXMNCiMjIGNsZWFuaW5nDQpgYGB7cn0NCg0KaGIgPC0gcmVhZF9jc3YoaGVyZSgiY2xlYW5fZGF0YS9oYl9saXN0X3NpbXBsZS5jc3YiKSkNCg0Kd2FpdGluZ190aW1lcyA8LSB3YWl0aW5nX3RpbWVzX3JhdyAlPiUgDQogIG11dGF0ZShkYXRlX3ltID0geW0obW9udGgpLCAuYmVmb3JlID0gbW9udGgsDQogICAgICAgICBtb250aCA9IG1vbnRoKGRhdGVfeW0sIGxhYmVsID0gVFJVRSwgYWJiciA9IEZBTFNFKSwNCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGVfeW0pKSAlPiUgDQogIGxlZnRfam9pbihoYiwgYygiaGJ0IiA9ICJoYiIpKSAlPiUgDQogIGxlZnRfam9pbihob3NwaXRhbHMsIGMoInRyZWF0bWVudF9sb2NhdGlvbiIgPSAibG9jYXRpb24iKSkgJT4lIA0KICByZW5hbWUodG90YWxfYXR0ZW5kYW5jZSA9IG51bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUsDQogICAgICAgICB3YWl0X2x0XzRocnMgPSBudW1iZXJfbWVldGluZ190YXJnZXRfYWdncmVnYXRlLA0KICAgICAgICAgd2FpdF9ndF84aHJzID0gYXR0ZW5kYW5jZV9ncmVhdGVyOGhycywNCiAgICAgICAgIHdhaXRfZ3RfMTJocnMgPSBhdHRlbmRhbmNlX2dyZWF0ZXIxMmhycywNCiAgICAgICAgIGhvc3BpdGFsX2lkID0gdHJlYXRtZW50X2xvY2F0aW9uLCANCiAgICAgICAgIGhvc3BpdGFsX25hbWUgPSBsb2NhdGlvbl9uYW1lKSAlPiUgDQogIHNlbGVjdChkYXRlX3ltLCB5ZWFyLCBtb250aCwgaGJfbmFtZSwgaG9zcGl0YWxfaWQsIGhvc3BpdGFsX25hbWUsIGRlcGFydG1lbnRfdHlwZSwNCiAgICAgICAgIHRvdGFsX2F0dGVuZGFuY2UsIHdhaXRfbHRfNGhycywgd2FpdF9ndF84aHJzLCB3YWl0X2d0XzEyaHJzKSAlPiUgDQogIG11dGF0ZSh3YWl0X2d0XzRocnMgPSB0b3RhbF9hdHRlbmRhbmNlIC0gd2FpdF9sdF80aHJzLCAuYWZ0ZXIgPSB3YWl0X2x0XzRocnMpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHRvdGFsX2F0dGVuZGFuY2U6d2FpdF9ndF8xMmhycywgLmZucyA9IH5jb2FsZXNjZSguLCAwKSkpDQoNCmBgYA0KDQojIyBhbmFseXNpcw0KYGBge3J9DQoNCndhaXRpbmdfdGltZXMgJT4lIA0KICBtdXRhdGUoaXNfY292aWRfeWVhciA9IGNhc2Vfd2hlbigNCiAgICB5ZWFyIDw9IDIwMTkgfiBGQUxTRSwNCiAgICB5ZWFyID49IDIwMjAgfiBUUlVFDQogICkpICU+JSANCiAgZ3JvdXBfYnkoaXNfY292aWRfeWVhcikgJT4lIA0KICBzdW1tYXJpc2Uoc3VtX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSksIA0KICAgICAgICAgICAgd2FpdF90YXJnZXQgPSBzdW0od2FpdF9sdF80aHJzKSkgJT4lIA0KICBwaXZvdF9sb25nZXIod2FpdF90YXJnZXQsIG5hbWVzX3RvID0gIndhaXRfdGltZSIsIHZhbHVlc190byA9ICJ2YWx1ZSIpICU+JSANCiAgbXV0YXRlKHByb3BvcnRpb24gPSB2YWx1ZSAvIHN1bV9hdHRlbmRhbmNlKSAlPiUgDQogIGdncGxvdChhZXMoeW1heCA9IHByb3BvcnRpb24sIHltaW4gPSAwLCB4bWF4ID0gMiwgeG1pbiA9IDEsIGZpbGwgPSBwcm9wb3J0aW9uKSkgKw0KICBnZW9tX3JlY3QoYWVzKHltYXggPSAxLCB5bWluID0gMCwgeG1heCA9IDIsIHhtaW4gPSAxKSwgZmlsbCA9ICJncmV5ODAiKSArDQogIGdlb21fcmVjdCgpICsgDQogIGNvb3JkX3BvbGFyKHRoZXRhID0gInkiLHN0YXJ0PS1waS8yKSArIHhsaW0oYygwLCAyKSkgKyB5bGltKGMoMCwyKSkgKw0KICBnZW9tX3RleHQoYWVzKHggPSAwLCB5ID0gMCwgbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQocHJvcG9ydGlvbiwgYWNjdXJhY3kgPSAwLjEpKSwgc2l6ZSA9IDYuNSkgKw0KICBnZW9tX3RleHQoYWVzKHggPSAwLjUsIHkgPSAxLjUpLCBsYWJlbCA9IGMoIlByZS1Db3ZpZCIsICJEdXJpbmcgQ292aWQiKSwgZmFtaWx5PSJQb3BwaW5zIExpZ2h0Iiwgc2l6ZT00LjIpICsgDQogIGZhY2V0X3dyYXAofmlzX2NvdmlkX3llYXIsIG5yb3cgPSAxKSArDQogIHRoZW1lX3ZvaWQoKSArDQogICMgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygicmVkIj0iI0M5MTQ2QyIsICJvcmFuZ2UiPSIjREE5MTEyIiwgImdyZWVuIj0iIzEyOTE4OCIpKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygicmVkIj0iI0M5MTQ2QyIsICJvcmFuZ2UiPSIjREE5MTEyIiwgImdyZWVuIj0iIzEyOTE4OCIpKSArDQogIHRoZW1lKHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQojICwNCiMgICAgICAgICAgKw0KICBsYWJzKHRpdGxlID0gIiAgIFBlcmNlbnRhZ2Ugb2YgYWRtaXNzaW9ucyBhY2hpZXZpbmcgdGFyZ2V0IHdhaXQgdGltZXMgKDw0aHJzKSIpDQoNCg0KYGBgDQoNCg0KYGBge3J9DQoNCmxpYnJhcnkoZ2dmb3JjZSkNCmxpYnJhcnkoc2NhbGVzKQ0KDQp3YWl0aW5nX3RpbWVzICU+JSANCiAgbXV0YXRlKGlzX2NvdmlkX3llYXIgPSBjYXNlX3doZW4oDQogICAgeWVhciA8PSAyMDE5IH4gRkFMU0UsDQogICAgeWVhciA+PSAyMDIwIH4gVFJVRQ0KICApKSAlPiUgDQogIGdyb3VwX2J5KGlzX2NvdmlkX3llYXIpICU+JSANCiAgc3VtbWFyaXNlKHN1bV9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpLCANCiAgICAgICAgICAgIHdhaXRfdGFyZ2V0ID0gc3VtKHdhaXRfbHRfNGhycykpICU+JSANCiAgcGl2b3RfbG9uZ2VyKHdhaXRfdGFyZ2V0LCBuYW1lc190byA9ICJ3YWl0X3RpbWUiLCB2YWx1ZXNfdG8gPSAidmFsdWUiKSAlPiUgDQogIG11dGF0ZShwcm9wb3J0aW9uID0gdmFsdWUgLyBzdW1fYXR0ZW5kYW5jZSkgJT4lDQogIG11dGF0ZSh5bWluID0gcmVzY2FsZSgwLCB0byA9IHBpKmMoLS41LC41KSwgZnJvbSA9IDA6MSksIA0KICAgICAgICAgeW1heCA9IHJlc2NhbGUocHJvcG9ydGlvbiwgdG8gPSBwaSpjKC0uNSwuNSksIGZyb20gPSAwOjEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4MCA9IDAsIHkwID0gMCwgcjAgPSAuNSwgciA9IDEpKSArIA0KICBnZW9tX2FyY19iYXIoYWVzKHN0YXJ0ID0gLSBwaSAvIDIsIGVuZCA9IHBpIC8gMiksIGZpbGwgPSAiZ3JleTgwIikgKw0KICBnZW9tX2FyY19iYXIoYWVzKHgwID0gMCwgeTAgPSAwLCByMCA9IC41LCByID0gMSwgc3RhcnQgPSB5bWluLCBlbmQgPSB5bWF4LCBmaWxsID0gcHJvcG9ydGlvbikpICsNCiAgY29vcmRfZml4ZWQoKSArDQogIGZhY2V0X3dyYXAofiBpc19jb3ZpZF95ZWFyKSArDQogIHlsaW0oLTAuMywgMSkgKw0KICBnZW9tX3RleHQoYWVzKHggPSAwLCB5ID0gMC4wMSwgbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQocHJvcG9ydGlvbiwgYWNjdXJhY3kgPSAwLjEpKSwgc2l6ZSA9IDYuNSkgKw0KICBnZW9tX3RleHQoYWVzKHggPSAwLCB5ID0gLTAuMjUpLCBsYWJlbCA9IGMoIlByZS1Db3ZpZCIsICJEdXJpbmcgQ292aWQiKSwgZmFtaWx5PSAiUG9wcGlucyBMaWdodCIsIHNpemU9NC4yKSArDQogIHRoZW1lX3ZvaWQoKSArDQogICAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMSksDQogICAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMCwgMCwgMCwgMCksICJjbSIpKSArDQogIGxhYnModGl0bGUgPSAiICAgUGVyY2VudGFnZSBvZiBhZG1pc3Npb25zIGFjaGlldmluZyB0YXJnZXQgd2FpdCB0aW1lcyAoPDRocnMpXG4iKQ0KDQogIA0KDQpgYGANCg0KIyBDb2xvdXIgcGFsZXR0ZQ0KDQpgYGB7cn0NCg0KcGFsIDwtIGMocmdiKDE5OSwgMTc1LCAxMTcsIG1heENvbG9yVmFsdWUgPSAyNTUpLA0KICAgICAgICAgcmdiKDEyNCwgMzYsIDI0LCBtYXhDb2xvclZhbHVlID0gMjU1KSwgDQogICAgICAgICByZ2IoMjEwLCAyMjEsIDIxMywgbWF4Q29sb3JWYWx1ZSA9IDI1NSksIA0KICAgICAgICAgcmdiKDE2OCwgMTA2LCA1NywgbWF4Q29sb3JWYWx1ZSA9IDI1NSksIA0KICAgICAgICAgcmdiKDIyMiwgMjI0LCAyMjcsIG1heENvbG9yVmFsdWUgPSAyNTUpLA0KICAgICAgICAgcmdiKDE4NiwgMTU4LCA1MywgbWF4Q29sb3JWYWx1ZSA9IDI1NSksIA0KICAgICAgICAgcmdiKDYsIDU3LCA4MywgbWF4Q29sb3JWYWx1ZSA9IDI1NSksIA0KICAgICAgICAgcmdiKDEwOSwgNjcsIDg1LCBtYXhDb2xvclZhbHVlID0gMjU1KQ0KKQ0KDQpzaG93X2NvbChwYWwpDQoNCg0KDQpgYGANCg0KIyBSb2IncyBwcm9ibGVtIA0KDQpgYGB7cn0NCg0KDQoNCiBpbnBhdGllbnRfYW5kX2RheWNhc2VfYnlfbmhzX2JvYXJkX29mX3RyZWF0bWVudF9hbmRfc2ltZF9ub25fY292aWRfY2xlYW5lZCAlPiUNCiAgc2VsZWN0KHF1YXJ0ZXJfeWVhciwgeWVhciwgaGJfbmFtZSwgc2ltZCwgYWRtaXNzaW9uX3R5cGUsIHN0YXlzLCBpc19jb3ZpZF95ZWFyKSAlPiUNCiAgZmlsdGVyKHN0YXlzID4wKSAlPiUNCiAgZmlsdGVyKGhiX25hbWUgIT0gIiIpICU+JQ0KICBmaWx0ZXIoIWlzLm5hKHNpbWQpKSAlPiUNCiAgZ3JvdXBfYnkoaXNfY292aWRfeWVhciwgc3RheXMsIHF1YXJ0ZXJfeWVhciwgc2ltZCkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9zdGF5cyA9IHN1bShzdGF5cykpICU+JQ0KICBkaXN0aW5jdCgpICU+JQ0KICBnZ3Bsb3QoKSsNCiAgYWVzKHggPSBxdWFydGVyX3llYXIsIHkgPSB0b3RhbF9zdGF5cywgZmlsbCA9IHNpbWQpKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIikNCg0KYGBgDQpgYGB7cn0NCmxpYnJhcnkocGxvdGx5KQ0KZGYgPC0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9wbG90bHkvZGF0YXNldHMvbWFzdGVyLzIwMTFfdXNfYWdfZXhwb3J0cy5jc3YiKQ0KZGYkaG92ZXIgPC0gd2l0aChkZiwgcGFzdGUoc3RhdGUsICc8YnI+JywgIkJlZWYiLCBiZWVmLCAiRGFpcnkiLCBkYWlyeSwgIjxicj4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZydWl0cyIsIHRvdGFsLmZydWl0cywgIlZlZ2dpZXMiLCB0b3RhbC52ZWdnaWVzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj4iLCAiV2hlYXQiLCB3aGVhdCwgIkNvcm4iLCBjb3JuKSkNCg0KZmlnIDwtIHBsb3RfZ2VvKGRmLCBsb2NhdGlvbm1vZGUgPSAnVVNBLXN0YXRlcycpDQpmaWcgPC0gZmlnICU+JSBhZGRfdHJhY2UoDQogICAgeiA9IH50b3RhbC5leHBvcnRzLCB0ZXh0ID0gfmhvdmVyLCBsb2NhdGlvbnMgPSB+Y29kZSwNCiAgICBjb2xvciA9IH50b3RhbC5leHBvcnRzLCBjb2xvcnMgPSAnUHVycGxlcycNCiAgKQ0KZmlnIDwtIGZpZyAlPiUgY29sb3JiYXIodGl0bGUgPSAiTWlsbGlvbnMgVVNEIikNCmZpZyA8LSBmaWcgJT4lIGxheW91dCgNCiAgICB0aXRsZSA9ICcyMDExIFVTIEFncmljdWx0dXJlIEV4cG9ydHMgYnkgU3RhdGU8YnI+KEhvdmVyIGZvciBicmVha2Rvd24pJw0KICApDQoNCmZpZw0KDQpgYGANCg0KYGBge3J9DQoNCmhlYWx0aF9ib2FyZF9tYXAgJT4lDQogIHBsb3RfZ2VvKGxvY2F0aW9ubW9kZSA9ICJTY290bGFuZCIpICU+JSANCiAgYWRkX3RyYWNlKHRleHQgPSB+aGJfbmFtZSkNCiAgICAgIGdncGxvdChhZXModGV4dCA9IGhiX25hbWUpKSArDQogICAgICBnZW9tX3NmKGZpbGwgPSBwYWxbNV0sIGNvbCA9ICJncmF5NDAiLCBzaXplID0gMC4xKSArDQogICAgICBnZW9tX3NmKGRhdGEgPSBoZWFsdGhfYm9hcmRfbWFwICU+JSBmaWx0ZXIoaGJfbmFtZSAlaW4lIGlucHV0JGhlYWx0aF9ib2FyZF9pbnB1dCksDQogICAgICAgICAgICAgIGZpbGwgPSBwYWxbN10sIHNpemUgPSAwLjEsIGNvbG91ciA9ICJ3aGl0ZSIpICsNCiAgICAgIHRoZW1lX3ZvaWQoKQ0KICAgIA0KICAgIGdncGxvdGx5KHAsDQogICAgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lIA0KICAgICAgY29uZmlnKHNjcm9sbFpvb20gPSBUUlVFLA0KICAgICAgICAgICAgIGRpc3BsYXlNb2RlQmFyID0gRiwNCiAgICAgICAgICAgICBzaG93QXhpc0RyYWdIYW5kbGVzID0gRikNCg0KYGBgDQoNCg==